Commit in lcio/src/java/hep/lcio/util on MAIN
FileUtil.java+66added 1.1
MergeFileOptions.java+74added 1.1
CommandLineTool.java+20-101.1 -> 1.2
MergeCommandHandler.java+157-381.1 -> 1.2
MergeUtil.java+203-791.2 -> 1.3
+520-127
2 added + 3 modified, total 5 files
JM: Improvements to merge command; read list of files; allow delta and starting time for each file

lcio/src/java/hep/lcio/util
FileUtil.java added at 1.1
diff -N FileUtil.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ FileUtil.java	26 Apr 2006 00:56:53 -0000	1.1
@@ -0,0 +1,66 @@
+package hep.lcio.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Miscellaneous java file utilities.
+ * @author jeremym
+ * @version $Id: FileUtil.java,v 1.1 2006/04/26 00:56:53 jeremy Exp $
+ */
+public abstract class FileUtil
+{
+	/**
+	 * Reads a file into an ArrayList.
+	 * @param fileName Name of the input file.
+	 * @return A List with one line String per entry.
+	 */
+	public static List loadFile(String fileName)
+	{
+		if ((fileName == null) || (fileName == ""))
+			throw new IllegalArgumentException();
+
+		String line;
+		ArrayList file = new ArrayList();
+
+		try
+		{
+			BufferedReader in = new BufferedReader(new FileReader(fileName));
+
+			if (!in.ready())
+				throw new IOException();
+
+			while ((line = in.readLine()) != null)
+				file.add(line);
+
+			in.close();
+		}
+		catch (IOException e)
+		{
+			System.out.println(e);
+			return null;
+		}
+
+		return file;
+	}
+	
+	/**
+	 * Return an array of files from an array of file paths.
+	 * @param fstr Array of file paths.
+	 * @return Array of File objects.
+	 */
+	public static File[] createFiles(String[] fstr)
+	{
+		File[] infiles = new File[fstr.length];
+		for (int i = 0; i < fstr.length; i++)
+		{
+			String ifile = (String) fstr[i];
+			infiles[i] = new File(ifile);
+		}
+		return infiles;
+	}
+}

lcio/src/java/hep/lcio/util
MergeFileOptions.java added at 1.1
diff -N MergeFileOptions.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ MergeFileOptions.java	26 Apr 2006 00:56:53 -0000	1.1
@@ -0,0 +1,74 @@
+package hep.lcio.util;
+
+import hep.lcio.event.LCEvent;
+import hep.lcio.implementation.io.LCFactory;
+import hep.lcio.io.LCReader;
+
+import java.io.File;
+import java.io.IOException;
+
+public final class MergeFileOptions
+{		
+	int nreads = 1;
+	float startt = 0;
+	float dt = 0;
+	File f;		
+	LCReader reader = LCFactory.getInstance().createLCReader();
+	
+	MergeFileOptions(File f, int nreads, float startt, float dt) throws IOException
+	{
+		this.f = f;
+		this.nreads = nreads;
+		this.startt = startt;
+		this.dt = dt;
+		
+		open();
+	}
+	
+	MergeFileOptions(File f) throws IOException
+	{
+		this.f = f;
+		
+		open();
+	}
+	
+	public int nreads()
+	{
+		return nreads;	
+	}
+	
+	public float startt()
+	{
+		return startt;
+	}
+	
+	public float dt()
+	{
+		return dt;
+	}
+	
+	public File file()
+	{
+		return f;
+	}
+	
+	public LCReader reader()
+	{
+		return reader;
+	}
+	
+	public void open() throws IOException
+	{
+		reader.open(file().getAbsolutePath());
+	}
+	
+	public void close() throws IOException
+	{
+		reader.close();
+	}
+	
+	public LCEvent nextEvent() throws IOException
+	{
+		return reader.readNextEvent();
+	}
+}
\ No newline at end of file

lcio/src/java/hep/lcio/util
CommandLineTool.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- CommandLineTool.java	24 Apr 2006 22:08:34 -0000	1.1
+++ CommandLineTool.java	26 Apr 2006 00:56:53 -0000	1.2
@@ -4,10 +4,11 @@
 import java.util.Iterator;
 import java.util.Map;
 
-//import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.HelpFormatter;
-//import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
+import org.apache.commons.cli.Parser;
+import org.apache.commons.cli.PosixParser;
 //import org.apache.commons.cli.Parser;
 //import org.apache.commons.cli.PosixParser;
 
@@ -27,17 +28,23 @@
  * @see hep.lcio.util.Split split
  * 
  * @author jeremym
- * @version $Id: CommandLineTool.java,v 1.1 2006/04/24 22:08:34 jeremy Exp $
+ * @version $Id: CommandLineTool.java,v 1.2 2006/04/26 00:56:53 jeremy Exp $
  */
-// TODO: Implement global options.
 public class CommandLineTool
 {
 	private Map handlers = new HashMap();
 	private String command;
-//	private Parser parser = new PosixParser();
+	private Parser parser = new PosixParser();
 	private Options options = new Options();
+	private CommandLine cl;
+	private static CommandLineTool instance = new CommandLineTool();
 	
-	public CommandLineTool()
+	public static CommandLineTool instance()
+	{
+		return instance;
+	}
+	
+	private CommandLineTool()
 	{
 		//System.out.println("CommandLineTool");
 
@@ -45,12 +52,17 @@
 		registerHandlers();
 	}	
 	
+	public CommandLine getGlobalOptions()
+	{
+		return cl;
+	}
+	
 	// main entry point.
 	public static void main(String[] args) throws Exception
 	{
 		//System.err.println("main");
 
-		CommandLineTool cl = new CommandLineTool();
+		CommandLineTool cl = CommandLineTool.instance();
 
 		// try {
 		cl.parse(args);
@@ -116,7 +128,6 @@
 		CommandHandler handler = getCommandHandler(getCommand());
 
 		// Global arguments.
-		/*
 		int nglob = icmd - 1;
 		String[] globargv = new String[0];
 		if (nglob > 0)
@@ -128,7 +139,6 @@
 				System.out.println("globargv[" + i + "]=" + globargv[i]);
 			}
 		}
-		*/
 
 		// Arguments are passed verbatim to the subcommand.
 		int ncmd = args.length - (icmd + 1);
@@ -140,7 +150,7 @@
 		}
 
 		// Parse global options.
-		//CommandLine cl = parser.parse(options, globargv);
+		cl = parser.parse(options, globargv);
 
 		// Pass the subcommand the command line options
 		// with globals stripped out.

lcio/src/java/hep/lcio/util
MergeCommandHandler.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- MergeCommandHandler.java	24 Apr 2006 22:08:34 -0000	1.1
+++ MergeCommandHandler.java	26 Apr 2006 00:56:53 -0000	1.2
@@ -1,8 +1,13 @@
 package hep.lcio.util;
 
 import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 
 import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.Parser;
@@ -10,11 +15,12 @@
 
 /**
  * This is the CommandHandler for the merge utility.
- * It handles command-line options and passes them
- * to methods in MergeUtil.
+ * 
+ * It parses 'lcio merge' command-line options and 
+ * passes the results to a method from MergeUtil.
  * 
  * @author jeremym
- * @version $Id: MergeCommandHandler.java,v 1.1 2006/04/24 22:08:34 jeremy Exp $
+ * @version $Id: MergeCommandHandler.java,v 1.2 2006/04/26 00:56:53 jeremy Exp $
  */
 public class MergeCommandHandler extends CommandHandler
 {
@@ -22,12 +28,16 @@
 	Options options = new Options();
 	File outfile;
 	File[] infiles;
-	float dt = 0;
-	boolean breakOnSingleEOF = false;
+	//float dt = 0;
 	int maxevents = Integer.MAX_VALUE;
-	int ntoread = 1;
-	boolean incrTime = false;
-
+	//int ntoread = 1;
+	//boolean incrTime = false;
+	List mergeFiles;
+
+	float def_dt = 0;
+	float def_startt = 0;
+	int def_ntoread = 1;
+	
 	/** 
 	 * MergeCommandHandler ctor. 
 	 */
@@ -48,31 +58,35 @@
 	{
 		Options options = new Options();
 
-		Option opt = new Option("o", false, "set the output file");
+		Option opt = new Option("o", false, "Set the output file.");
 		opt.setArgs(1);
 		options.addOption(opt);
 
-		opt = new Option("i", false, "add an input file");
+		opt = new Option("i", false, "Add an input file.");
 		opt.setArgs(1);
 		options.addOption(opt);
 
-		opt = new Option("t", true, "set delta time (NS)");
+		opt = new Option("t", true, "Set delta time (ns).");
 		opt.setArgs(1);
 		options.addOption(opt);
-
-		opt = new Option("d", false, "increment t after each overlay event");
+		
+		opt = new Option("T", true, "Set the starting time (ns).");
 		opt.setArgs(1);
 		options.addOption(opt);
 
-		opt = new Option("n", true, "set maximum number of events");
+		opt = new Option("n", true, "Set maximum number of output events.");
 		opt.setArgs(1);
 		options.addOption(opt);
 
-		opt = new Option("c", true, "continue when one of the input files runs out of events (default is stop processing)");
+		opt = new Option("e", true, "Set number of events to merge in from each input file per merged event.  (Default is 1)");
+		opt.setArgs(1);
 		options.addOption(opt);
-
-		opt = new Option("e", true, "set number of events at a time to merge in from each input file (default is 1)");
-
+		
+		opt = new Option("f", true, "Set input file list with format: [file_name],[n_reads_per_event],[start_time],[delta_time]" +
+				"This option is not usable with the -i argument.");
+		opt.setArgs(1);
+		options.addOption(opt);
+		
 		return options;
 	}
 
@@ -84,40 +98,61 @@
 	{
 		CommandLine cl = parser.parse(options, argv);
 
-		// Make an input file list.
+		// Must have at least one of -i or -f.
+		if (!cl.hasOption("i") && !cl.hasOption("f"))
+		{
+			System.err.println("The merge command requires one of the -i or -f options.");
+		}
+		// Cannot have both -i and -f.
+		else if (cl.hasOption("i") && cl.hasOption("f"))
+		{
+			System.err.println("The -i and -f options cannot be used together.");
+			printUsage(true);
+		}
+		
+		// Read a file containing comma-delimited list of fname and nreads.
+		if (cl.hasOption("f"))
+		{
+			mergeFiles = createMergeFiles(FileUtil.loadFile(cl.getOptionValue("f")));
+		}
+		
+		// Add input files one-by-one.
 		if (cl.hasOption("i"))
 		{	
-			infiles = MergeUtil.createFiles(cl.getOptionValues("i"));
+			// Create input file array.
+			infiles = FileUtil.createFiles(cl.getOptionValues("i"));
+			
+			// Create default merge files.
+			mergeFiles = createDefaultMergeFiles(infiles);
 		}
 
-		// DEBUG
-		System.err.println("outfile=" + cl.getOptionValue("o"));
-
 		// Output file.
-		outfile = new File(cl.getOptionValue("o"));
-
-		// The time delta.
-		if (cl.hasOption("t"))
+		if (cl.hasOption("o"))
 		{
-			dt = Float.parseFloat(cl.getOptionValue("t"));
+			outfile = new File(cl.getOptionValue("o"));
+		}
+		else {
+			outfile = new File("merged_events.slcio");
 		}
+		
+		System.err.println("Set output file: " + outfile.getAbsolutePath());
 
-		// Set whether to break on a single EOF from input files.
-		if (cl.hasOption("c"))
+		// Set the default time delta.
+		if (cl.hasOption("t"))
 		{
-			breakOnSingleEOF = false;
+			def_dt = Float.parseFloat(cl.getOptionValue("t"));
 		}
 
-		// Set max events.
-		if (cl.hasOption("n"))
+		// Set the default start time.
+		if (cl.hasOption("T"))
 		{
-			maxevents = Integer.parseInt(cl.getOptionValue("n"));
+			def_startt = Float.parseFloat(cl.getOptionValue("T"));
 		}
 
-		// Set whether to increment the time delta after each event overlay.
-		if (cl.hasOption("d"))
+		// Set the maximum number of merged events.
+		if (cl.hasOption("n"))
 		{
-			incrTime = true;
+			this.def_ntoread = Integer.parseInt(cl.getOptionValue("n"));
 		}
 	}
 
@@ -126,6 +161,90 @@
 	 */
 	public void execute() throws Exception
 	{
-		MergeUtil.mergeFiles(outfile, infiles, ntoread, maxevents, dt, incrTime);
+		MergeUtil.mergeFiles(outfile, mergeFiles, maxevents);
+	}
+	
+	/**
+	 * Create a map of input files to number of reads to do per output (merged) event.
+	 * @param lines File lines read from input file list (-f option).
+	 * @return Map of File to number of reads per merged event.
+	 */
+	public List createMergeFiles(List lines) throws IOException
+	{	
+		List mfiles = new ArrayList();
+	
+		for (Iterator iter = lines.iterator(); iter.hasNext();)
+		{
+			// Get the next line.	
+			String line = (String)iter.next();
+			
+			// Split into fields on comma.
+			String[] fields = line.split(",");
+			
+			if (fields.length != 0)
+			{
+				// Get file name.
+				String fname = fields[0];
+				
+				// Get number of reads per event for this file.
+				int nreads = def_ntoread;
+				if (fields.length > 1)
+					nreads = Integer.parseInt(fields[1]);
+				
+				// Get start time.
+				float startt = def_startt;
+				if (fields.length > 2)
+					startt = Float.parseFloat(fields[2]);
+				
+				// Get delta time.
+				float dt = def_dt;
+				if (fields.length > 3)
+					dt = Float.parseFloat(fields[3]);	
+				
+				// Create the input file.
+				File f = new File(fname);
+				
+				// Create the merge file object.
+				MergeFileOptions fopt = new MergeFileOptions(f, nreads, startt, dt);
+				
+				// Add this file with options to merge files list.
+				mfiles.add(fopt);
+			}
+		}
+		return mfiles;
+	}
+	
+	/**
+	 * Create the default merge options, which is one event from the file per merged output event.
+	 * @param files An array of input Files.
+	 * @return A Map of File to Integer specifiying number of reads to do from that file per merged output event.
+	 */
+	public List createDefaultMergeFiles(File[] files) throws IOException
+	{
+		List m = new ArrayList();
+		if (files != null)
+		{
+			for (int i=0; i<files.length;i++)
+			{
+				m.add(new MergeFileOptions(files[i], def_ntoread, def_startt, def_dt));
+			}			
+		}
+		return m;
+	}
+	
+	/**
+	 * Print usage and (optionally) exit the program.
+	 * @param doExit Whether or not to exit after printing usage.
+	 */
+	public void printUsage(boolean doExit)
+	{
+		HelpFormatter help = new HelpFormatter();
+
+		help.printHelp("LCIO Merge command", "merge command", options, "");
+
+		if (doExit)
+		{
+			System.exit(0);
+		}
 	}
 }
\ No newline at end of file

lcio/src/java/hep/lcio/util
MergeUtil.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- MergeUtil.java	25 Apr 2006 21:58:16 -0000	1.2
+++ MergeUtil.java	26 Apr 2006 00:56:53 -0000	1.3
@@ -16,51 +16,46 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 /**
  * Utility methods for merging LCIO files, events, and collections,
- * with possible application of time delta.
+ * with optional application of a time delta per event.
  * 
  * @author jeremym
- * @version $Id: MergeUtil.java,v 1.2 2006/04/25 21:58:16 jeremy Exp $
+ * @version $Id: MergeUtil.java,v 1.3 2006/04/26 00:56:53 jeremy Exp $
  */
 abstract public class MergeUtil
-{	
+{		
 	/** 
 	 * Merge nEventsToRead events from each File in infiles into a single event in outfile,
 	 * until records in infiles are exhausted or maxevents are created. 
 	 * @return The number of combined events created.
-	 * @param outfile Output target file.
-	 * @param infiles Input events to merge in.
-	 * @param nEventsToRead Number of events to read at once into one output event.
-	 * @param maxEventsToWrite Maximum number of output events to create.
+	 * @param outfile Output target file containing the merged events.
+	 * @param fileMap Map of File to Integer, specifying number of events to read from that file per merge.
+	 * @param maxEventsToWrite Set the maximum number of merged events that this method will create.
 	 * @param dt The time delta.
 	 */
 	public static int mergeFiles( 
 			File outfile, 
-			File[] infiles, 
-			int nEventsToRead, 
-			int maxEventsToWrite, 
-			float dt,
-			boolean incrTime) throws IOException
-	{
+			List mergeFiles,
+			int maxEventsToWrite) throws IOException
+	{		
 		// Create the writer.
 		LCWriter writer = LCFactory.getInstance().createLCWriter();
 		
 		// Open the writer for the new file containing the merged events.
 		writer.open(outfile.getCanonicalPath(), LCIO.WRITE_NEW);
-
-		// Create the array of LCReaders.
-		LCReader[] readers = createReaders(infiles);
-
+		
 		// Count of total output events.
 		int nevents = 0;
 
 		// File read loop.
 		for (;;)
-		{
-			System.err.println("nevents: " + nevents);
-
+		{			
 			// Check if max output events is reached.
 			if (nevents >= maxEventsToWrite)
 				break;
@@ -76,16 +71,32 @@
 			int totmerged = 0;
 
 			// Loop over the readers.
-			for (int i = 0; i < readers.length; i++)
-			{
+			for (Iterator iter = mergeFiles.iterator(); iter.hasNext(); )
+			{							
 				// Get the next reader.
-				LCReader reader = readers[i];
+				MergeFileOptions mfile = (MergeFileOptions)iter.next();
+				
+				// Get number of events to read.
+				int nEventsToRead = mfile.nreads();
 
-				// Merge ntoread events from this reader into target with delta time of dt.
-				int nmerged = MergeUtil.mergeEvents(target, reader, nEventsToRead, setEventHeader, dt, incrTime);
+				// Get the reader.
+				LCReader reader = mfile.reader();
 
-				// DEBUG
-				System.err.println("nmerged: " + nmerged);
+				// Get starting time.
+				float startt = mfile.startt();
+				
+				// Get delta time.
+				float dt = mfile.dt();
+				
+				// Merge ntoread events from this reader into target,
+				// using starting time of startt, delta time of dt.
+				int nmerged = MergeUtil.mergeEvents(
+						target, 
+						reader, 
+						nEventsToRead, 
+						setEventHeader,
+						startt,
+						dt);
 
 				// Increment total merged.
 				totmerged += nmerged;
@@ -96,9 +107,7 @@
 
 			// Write out the combined event if something got merged in.
 			if (totmerged > 0)
-			{
-				//System.err.println("totmerged: " + totmerged);
-
+			{				
 				writer.writeEvent(target);
 				nevents++;
 			}
@@ -109,11 +118,17 @@
 			}
 		} // file read loop
 
+		System.out.println("Created " + nevents + " merged events.");
+		
 		// Close the writer.
 		writer.close();
 
 		// Close the readers.
-		closeReaders(readers);
+		//closeReaders(readers);
+		for (Iterator iter = mergeFiles.iterator(); iter.hasNext(); )
+		{			
+			try { ((MergeFileOptions)iter.next()).close(); } catch (Exception x) {}
+		}
 		
 		// Return number of events created.
 		return nevents;
@@ -132,14 +147,14 @@
 			LCReader overlayEvents, 
 			int ntoread, 			 
 			boolean setEventHeader,
-			float dt,
-			boolean incrTime) throws IOException
-	{
+			float startt,
+			float dt) throws IOException
+	{	
 		// Read the next event from the reader.
-		LCEvent nextOverlayEvent = overlayEvents.readNextEvent();
+		LCEvent nextEvent = overlayEvents.readNextEvent();
 
 		// Return 0 if reader is exhausted.
-		if (nextOverlayEvent == null)
+		if (nextEvent == null)
 		{
 			return 0;
 		}
@@ -148,26 +163,36 @@
 		if (setEventHeader)
 		{
 			ILCEvent itargetEvent = (ILCEvent) targetEvent;
-			itargetEvent.setDetectorName(nextOverlayEvent.getDetectorName());
-			itargetEvent.setEventNumber(nextOverlayEvent.getEventNumber());
-			itargetEvent.setRunNumber(nextOverlayEvent.getRunNumber());
-			itargetEvent.setTimeStamp(nextOverlayEvent.getTimeStamp());
+			itargetEvent.setDetectorName(nextEvent.getDetectorName());
+			itargetEvent.setEventNumber(nextEvent.getEventNumber());
+			itargetEvent.setRunNumber(nextEvent.getRunNumber());
+			itargetEvent.setTimeStamp(nextEvent.getTimeStamp());
 		}
 
-		// Read ntoread events from reader and merge into targetEvent.
+		// Number of events merged in.
 		int nevt = 0;
-		float time = dt;
-		for (; nevt < ntoread && nextOverlayEvent != null; nevt++)
-		{
+		
+		// Set starting time.
+		float time = startt;
+		
+		// Read loop.
+		while (nextEvent != null)
+		{	
 			// Merge single overlay event onto targetEvent.
-			mergeSingleEvent((ILCEvent) targetEvent, nextOverlayEvent, dt);
-
+			mergeSingleEvent((ILCEvent) targetEvent, nextEvent, dt);		
+			
+			// Increment number of events read.
+			nevt++;
+			
+			// Break if read max num events.
+			if (nevt >= ntoread)
+				break;
+			
 			// Get next event to merge in. (could be null)
-			nextOverlayEvent = overlayEvents.readNextEvent();
+			nextEvent = overlayEvents.readNextEvent();
 			
-			// Increment the delta time for next event.
-			if (incrTime)
-				time += dt;
+			// Increment the time for next event.
+			time += dt;						
 		}
 
 		// Return the number of events that were overlayed.
@@ -276,14 +301,11 @@
 
 				// Find a matching hit in target collection.
 				ISimCalorimeterHit thit = findMatching(targetColl, ohit);
-
-				if (thit != null)
-					System.err.println("existing hit");
 				
 				// No matching hits?
 				if (thit == null)
 				{
-					System.out.println("new hit");
+					//System.out.println("new hit");
 
 					// Copy the overlay hit without MCParticle contributions.
 					thit = copy(ohit);
@@ -298,13 +320,9 @@
 		}
 		// Handle an MCParticle collection.
 		else if (colltype.compareTo(LCIO.MCPARTICLE) == 0)
-		{
-			System.err.println("mcparticle");
-			
+		{		
 			for (int ii = 0; ii < overlayColl.size(); ii++)
-			{
-				System.err.println("mcp #: " + ii);
-				
+			{				
 				// Get the next MCParticle to add in.
 				IMCParticle p = (IMCParticle) overlayColl.getElementAt(ii);
 
@@ -380,7 +398,6 @@
 		// Get the hit energy.
 		float e = hit.getEnergy();
 		
-		//System.err.println("nmcp: " + hit.getNMCContributions());
 		for (int j = 0; j < hit.getNMCContributions(); j++)
 		{
 			// PDGID might not be set.
@@ -392,8 +409,7 @@
 			catch (Exception x)
 			{}
 
-			// Add this MCContrib to the existing hit, applying dt.
-			System.err.println("mcp contrib e: " + hit.getEnergyCont(j));
+			// Add this MCParticle contribution.
 			target.addMCParticleContribution(
 					hit.getParticleCont(j), 
 					hit.getEnergyCont(j), 
@@ -420,13 +436,12 @@
 		newhit.setCellID0(hit.getCellID0());
 		newhit.setCellID1(hit.getCellID1());
 		newhit.setPosition(hit.getPosition());
-		System.err.println("copied calhit pos: " + hit.getPosition()[0] + hit.getPosition()[1] + hit.getPosition()[2]);
 		return newhit;
 	}
 
 	/** 
 	 * Shallow copy an LCCollection.  
-	 * Do not copy LCObject members.
+	 * Does not copy LCObject members.
 	 * @return A copy of collection. 
 	 * @param coll The LCCollection to be copied.
 	 */
@@ -461,6 +476,37 @@
 		}
 		return readers;
 	}
+	
+	/**
+	 * Create a Map of LCReader to Integer from a Map of File to Integer. 
+	 * @param fileMap Input map of File to Integer.
+	 * @return Map of LCReader to Integer (number of reads per merged event).
+	 * @throws IOException
+	 */
+	public static Map createReadMap(Map fileMap) throws IOException
+	{
+		Map readMap = new HashMap();
+
+		for (Iterator iter=fileMap.keySet().iterator(); iter.hasNext();)
+		{
+			// Create a new reader.
+			LCReader reader = LCFactory.getInstance().createLCReader();
+
+			// Get the next file.
+			File f = (File)iter.next();
+
+			// Open the reader.
+			reader.open(f.getCanonicalPath());
+			
+			// Get number of events to read per merge.
+			Integer nreads = (Integer)fileMap.get(f);
+			
+			// Map the reader to number of reads.
+			readMap.put(reader, (Object)nreads);
+		}
+		
+		return readMap;
+	}
 
 	/** 
 	 * Close all of the readers.
@@ -481,22 +527,100 @@
 		}
 	}
 	
-	/**
-	 * Return an array of files from an array of file paths.
-	 * @param fstr Array of file paths.
-	 * @return Array of File objects.
-	 */
-	public static File[] createFiles(String[] fstr)
+
+}
+
+/** 
+ * Merge nEventsToRead events from each File in infiles into a single event in outfile,
+ * until records in infiles are exhausted or maxevents are created. 
+ * @return The number of combined events created.
+ * @param outfile Output target file.
+ * @param infiles Input events to merge in.
+ * @param nEventsToRead Number of events to read at once into one output event.
+ * @param maxEventsToWrite Maximum number of output events to create.
+ * @param dt The time delta.
+ */
+/*
+public static int mergeFiles( 
+		File outfile, 
+		File[] infiles, 
+		int nEventsToRead, 
+		int maxEventsToWrite, 
+		float dt,
+		boolean incrTime) throws IOException
+{
+	// Create the writer.
+	LCWriter writer = LCFactory.getInstance().createLCWriter();
+	
+	// Open the writer for the new file containing the merged events.
+	writer.open(outfile.getCanonicalPath(), LCIO.WRITE_NEW);
+
+	// Create the array of LCReaders.
+	LCReader[] readers = createReaders(infiles);
+
+	// Count of total output events.
+	int nevents = 0;
+
+	// File read loop.
+	for (;;)
 	{
-		File[] infiles = new File[fstr.length];
-		for (int i = 0; i < fstr.length; i++)
+		System.err.println("nevents: " + nevents);
+
+		// Check if max output events is reached.
+		if (nevents >= maxEventsToWrite)
+			break;
+
+		// Create the new output event.
+		ILCEvent target = new ILCEvent();
+
+		// First time, the event header needs to
+		// be set from the first LCEvent read.
+		boolean setEventHeader = true;
+
+		// Total events merged in from all sources in this pass.
+		int totmerged = 0;
+
+		// Loop over the readers.
+		for (int i = 0; i < readers.length; i++)
 		{
-			String ifile = (String) fstr[i];
-			infiles[i] = new File(ifile);
+			// Get the next reader.
+			LCReader reader = readers[i];
+
+			// Merge ntoread events from this reader into target with delta time of dt.
+			int nmerged = MergeUtil.mergeEvents(target, reader, nEventsToRead, setEventHeader, dt, incrTime);
 
 			// DEBUG
-			//System.out.println("added input file: " + ifile);
+			System.err.println("nmerged: " + nmerged);
+
+			// Increment total merged.
+			totmerged += nmerged;
+
+			// Next time, don't need to set the header.
+			setEventHeader = false;
 		}
-		return infiles;
-	}
-}
\ No newline at end of file
+
+		// Write out the combined event if something got merged in.
+		if (totmerged > 0)
+		{
+			//System.err.println("totmerged: " + totmerged);
+
+			writer.writeEvent(target);
+			nevents++;
+		}
+		else
+		{
+			// Done!
+			break;
+		}
+	} // file read loop
+
+	// Close the writer.
+	writer.close();
+
+	// Close the readers.
+	closeReaders(readers);
+	
+	// Return number of events created.
+	return nevents;
+}
+*/
CVSspam 0.2.8