diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets2.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets2.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets2.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets2.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 68,73 ****
--- 68,74 ----
  
  	public boolean notFull(Packet p) throws RtStpsException {
  
+ 		System.out.println("ATMS not full");
  		// collect time info
  		if (p.isFirstPacketInSequence() || p.isStandalonePacket()) {
  			calcTimeSpanInSeconds(p);
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets3.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets3.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets3.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets3.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 2,194 ****
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
! */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
  import gov.nasa.gsfc.drl.rtstps.core.ccsds.Packet;
  
  /**
!  * Build the RawApplicationPackets (or read a pre-existing one) for the HDF for ATMS.
!  * This version uses the scan start bit to collect scan lines to make granules of 32 secs
!  * worth approximately.
   * 
-  * Current 
-  *
   */
  public class ATMSRawApplicationPackets3 extends RawApplicationPackets {
- 	
- 	private final int scansPerGranule = 12; // approx 32 secs worth
- 	//private final int sciPacketsPerScan = 104;
  
  
  	private Stats stats = null;
  
! 	private int scanCount = -1;  // FIXME there was a bug in VIIRS module and this should be zero and check below should >= I think...
! 	
! 	
! 	//private boolean scanCheck = false;
! 	
  	private int sciPacketCount = 0;
  
  	/**
! 	 * Constructor for creating an nth instance of a ATMS raw application data packet area builder.
! 	 * @param satellite  the name of the spacecraft as a SpacecraftId
! 	 * @param setNum  the set number
! 	 * @param scansPerGranule the number of sensor scans per granule
  	 */
! 	public ATMSRawApplicationPackets3(SpacecraftId satellite, int setNum, int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.ATMS_Science, setNum, packetPool);
! 		
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
  	}
- 	
  
! 	public ATMSRawApplicationPackets3(Stats stats, SpacecraftId satellite, int setNum, int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.ATMS_Science, setNum, packetPool);
! 		
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
  		this.stats = stats;
  	}
! 	
  	/**
! 	 * Constructor which attempts to read the RawApplicationPacket entry that pre-exists.
! 	 * The contents of the dataspace are read into a memory buffer... assuming it will fit.
! 	 * @param allRDRId  the rdrAll Groups id
! 	 * @param setNum the set number of raw entry
! 	 * @throws RtStpsException Wraps any HDF exception
  	 */
! 	public ATMSRawApplicationPackets3(int allRDRId, int setNum) throws RtStpsException {
  		super(allRDRId, setNum);
  	}
! 	
! 	public ATMSRawApplicationPackets3(int readId, int setNum, boolean usedByGranuleOnly) throws RtStpsException {
  		super(readId, setNum, true);
  	}
! 	
  
  	public boolean notFull(Packet p) throws RtStpsException {
  
! 		// when the scan start flag goes high in 528
! 		// collect packets until it flips again
! 		// when it flips, that's one scan's worth...
! 		// count the transitions, when a granules worth it collected
! 		// then its time to write them
! 		// we 
! 		
! 		if (p.isStandalonePacket() && p.hasSecondaryHeader()) {
! 			if (p.getApplicationId() == 528) {
! 				byte[] data = p.getData();
! 				int offset = 6 + 8 + 2;
! 				int scanStart = ((int)data[offset] >>> 7) & 0x00000001;
! 				if (scanStart == 1) {
  					
- 						++scanCount;
  					
  				}
  			}
  		}
! 		return (scanCount < scansPerGranule);  // true == not full, false == full
  	}
- 	
- 	
  
! 	
  
  	@Override
  	public void put(Packet p) throws RtStpsException {
! 		
! 		if (scanCount < 0) { // throw away any initial packets if we've not seen the start of a scan...
! 			if (stats == null) {
! 				//System.out.println("Trimming ATMS [" + p.getApplicationId() + "]");
! 			} else {
! 				//stats.sci_trimmedPackets.value++;
! 			}
! 			return;
! 		}
  		sciPacketCount++;
! 		
  		this.updateAppIdCounters(p.getApplicationId());
! 		
  		RDRName rdrName = RDRName.fromAppId(p.getApplicationId());
! 		
  		if (rdrName != RDRName.ATMS_Science) {
! 			throw new RtStpsException("Not a ATMS science packet [" + p.getApplicationId() + "]");
  		}
! 	
! 		
  		// collect time info
  		if (p.hasSecondaryHeader()) {
  
! 
! 			// secondary time stamp only valid in in first or standalone packets...
  			if (getFirstTime() == 0L) {
! 				//System.out.println("Here...");
  				setFirstTime(p.getTimeStamp(8));
  			}
! 			
  			setLastTime(p.getTimeStamp(8));
  		}
! 	
  		Packet pcopy = CopyPacket.deep(p, packetPool);
! 		
  		getPacketList().add(pcopy);
  
  	}
! 	
! 	
  	/**
! 	 * Write the ATMSRawApplication structure to the given HDF file specified by the HDF input handle
! 	 * @param hdfFile input handle to a previous opened HDF file
  	 * @return true if the write succeeds
! 	 * @throws RtStpsException Wraps HDF exceptions
  	 */
  	@Override
  	public boolean write(int hdfFile) throws RtStpsException {
  		boolean ret = false;
  		if (this.scanCount < this.scansPerGranule) {
  			if (stats == null) {
! 				System.out.println("Deleting partial ATMS Granule -- [" + this.scanCount + "] scans, collected packets [" + this.sciPacketCount + "]");
  			} else {
  				stats.sci_discardedGranules.value++;
! 			}	
  			ret = false;
  		} else {
  			if (stats == null) {
! 				System.out.println("Creating ATMS granule of [" + this.scanCount + "] scans");
  			} else {
  				stats.sci_createdGranules.value++;
  			}
  			super.write(hdfFile);
  			ret = true;
! 			
  		}
! 		
! 		System.out.println("ATMS Sci packets in granule: " + sciPacketCount + " Packet per scan: " + (float)sciPacketCount / (float)scansPerGranule);
! 		System.out.println("ATMS app ids = " + super.appIdCountersToString(scansPerGranule));
  		scanCount = -1;
! 		
  		sciPacketCount = 0;
  
  		return ret;
  	}
- 	
  
- 	
  	/**
! 	 * Close out the RawApplicationPacket which writes the results to the HDF file and cleans up.
  	 */
  	public void close() throws RtStpsException {
  		super.close();
! 		
  		scanCount = -1;
! 		
! 		
! 		
  		sciPacketCount = 0;
  	}
  
--- 2,303 ----
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
!  */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
  import gov.nasa.gsfc.drl.rtstps.core.ccsds.Packet;
  
  /**
!  * Build the RawApplicationPackets (or read a pre-existing one) for the HDF for
!  * ATMS. This version uses the scan start bit to collect scan lines to make
!  * granules of 32 secs worth approximately.
!  * 
!  * Current
   * 
   */
  public class ATMSRawApplicationPackets3 extends RawApplicationPackets {
  
+ 	private final int scansPerGranule = 12; // approx 32 secs worth
+ 	// private final int sciPacketsPerScan = 104;
  
  	private Stats stats = null;
  
! 	private int scanCount = -1; // FIXME there was a bug in VIIRS module and
! 								// this should be zero and check below should >=
! 								// I think...
! 
! 	// private boolean scanCheck = false;
! 
  	private int sciPacketCount = 0;
  
  	/**
! 	 * Constructor for creating an nth instance of a ATMS raw application data
! 	 * packet area builder.
! 	 * 
! 	 * @param satellite
! 	 *            the name of the spacecraft as a SpacecraftId
! 	 * @param setNum
! 	 *            the set number
! 	 * @param scansPerGranule
! 	 *            the number of sensor scans per granule
  	 */
! 	public ATMSRawApplicationPackets3(SpacecraftId satellite, int setNum,
! 			int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.ATMS_Science, setNum, packetPool);
! 
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
  	}
  
! 	public ATMSRawApplicationPackets3(Stats stats, SpacecraftId satellite,
! 			int setNum, int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.ATMS_Science, setNum, packetPool);
! 
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
  		this.stats = stats;
  	}
! 
  	/**
! 	 * Constructor which attempts to read the RawApplicationPacket entry that
! 	 * pre-exists. The contents of the dataspace are read into a memory
! 	 * buffer... assuming it will fit.
! 	 * 
! 	 * @param allRDRId
! 	 *            the rdrAll Groups id
! 	 * @param setNum
! 	 *            the set number of raw entry
! 	 * @throws RtStpsException
! 	 *             Wraps any HDF exception
  	 */
! 	public ATMSRawApplicationPackets3(int allRDRId, int setNum)
! 			throws RtStpsException {
  		super(allRDRId, setNum);
  	}
! 
! 	public ATMSRawApplicationPackets3(int readId, int setNum,
! 			boolean usedByGranuleOnly) throws RtStpsException {
  		super(readId, setNum, true);
  	}
! 
! 	private static long firstTime = 0;
  
  	public boolean notFull(Packet p) throws RtStpsException {
+ 		// every appearance of 1289 means start of scan
+ 		boolean notFull = true;
+ 
+ 		long timestamp = p.getTimeStamp(8);
+ 
+ 		GranuleId currentGranId = new GranuleId(SpacecraftId.npp,
+ 				p.getTimeStamp(8), RDRName.ATMS_Science);
+ 
+ 		// System.out.printf("VIIRS: Gran %s seq %d ts %d obs %d \n",
+ 		// currentGranId.toString(), p.getSequenceCounter(),
+ 		// timestamp, obsTime.getMicrosSinceEpoch());
+ 
+ 		if (currentGranId.toString().startsWith("NPP-") == false) {
+ 
+ 			if (ATMSRawApplicationPackets3.firstTime < 0l) {
+ 				ATMSRawApplicationPackets3.firstTime = timestamp;
+ 				setFirstTime(timestamp);
+ 				scanCount = 0;
+ 			} else {
+ 				GranuleId startGranId = new GranuleId(SpacecraftId.npp,
+ 						getFirstTime(), RDRName.ATMS_Science);
+ 
+ 				if (startGranId.toString().contentEquals(
+ 						currentGranId.toString()) == false) {
  
! 
! 					LeapDate lpd = new LeapDate(getFirstTime());
! 					long startIET = lpd.getMicrosSinceEpoch();
! 					long startTime = GranuleId.calcGranuleStartTime(startIET,
! 							RDRName.ATMS_Science);
! 					
! 					long endTime = GranuleId.calcGranuleEndTime(startIET,
! 							RDRName.ATMS_Science);
! 
! 					
! 					
! 
! 					lpd = new LeapDate(p.getTimeStamp(8));
! 					long currentIET = lpd.getMicrosSinceEpoch();
! 	
! //					System.out.printf("ATMS: %d <= %d <= %d id %d\n", startIET,currentIET, endTime,p.getSequenceCounter() );
! 					
  					
  					
+ 					if  
+ 					(!(( startIET <= currentIET ) &&
+ 					(endTime  >=  currentIET) ))
+ 					{
+ 						System.out.println("ATMS: " + startGranId.toString()
+ 								+ " Current:" + currentGranId.toString());
+ 
+ 						System.out.printf("ATMS: %d <= %d <= %d id %d\n", startIET,currentIET, endTime,p.getSequenceCounter() );
+ 						
+ 						ATMSRawApplicationPackets3.firstTime = -1;
+ 						notFull = false; // if 20secs have gone by, the granule
+ 					}
+ 					
+ //					long stNext = GranuleId.calcGranuleStartTime(currentIET,
+ //							RDRName.ATMS_Science);
+ 
+ //					System.out.printf(
+ //							"ATMS ietthis: %d start: %d Next %d %d\n",
+ //							ietTimeThis, stThis, ietTimeNext, stNext);
+ 
+ //					if (stThis != stNext) 
+ //					{
+ //						
+ //						System.out.println("ATMS: " + startGranId.toString()
+ //								+ " Current:" + currentGranId.toString());
+ //
+ //						
+ //						ATMSRawApplicationPackets3.firstTime = -1;
+ //						notFull = false; // if 20secs have gone by, the granule
+ //					}
+ 
+ 				} else
+ 
+ 				{
+ 					scanCount++;
+ 					setLastTime(timestamp);
  				}
+ 
  			}
  		}
! 
! 		return notFull;
! 
  	}
  
! 	// public boolean notFull(Packet p) throws RtStpsException {
! 	//
! 	// // when the scan start flag goes high in 528
! 	// // collect packets until it flips again
! 	// // when it flips, that's one scan's worth...
! 	// // count the transitions, when a granules worth it collected
! 	// // then its time to write them
! 	// // we
! 	// System.out.println("ATMS not full3");
! 	//
! 	// if (p.isStandalonePacket() && p.hasSecondaryHeader()) {
! 	// if (p.getApplicationId() == 528) {
! 	// byte[] data = p.getData();
! 	// int offset = 6 + 8 + 2;
! 	// int scanStart = ((int)data[offset] >>> 7) & 0x00000001;
! 	// if (scanStart == 1) {
! 	//
! 	// ++scanCount;
! 	//
! 	// }
! 	// }
! 	// }
! 	// return (scanCount < scansPerGranule); // true == not full, false == full
! 	// }
  
  	@Override
  	public void put(Packet p) throws RtStpsException {
! 
! 		// if (scanCount < 0) { // throw away any initial packets if we've not
! 		// seen the start of a scan...
! 		// if (stats == null) {
! 		// //System.out.println("Trimming ATMS [" + p.getApplicationId() + "]");
! 		// } else {
! 		// //stats.sci_trimmedPackets.value++;
! 		// }
! 		// return;
! 		// }
  		sciPacketCount++;
! 
  		this.updateAppIdCounters(p.getApplicationId());
! 
  		RDRName rdrName = RDRName.fromAppId(p.getApplicationId());
! 
  		if (rdrName != RDRName.ATMS_Science) {
! 			throw new RtStpsException("Not a ATMS science packet ["
! 					+ p.getApplicationId() + "]");
  		}
! 
  		// collect time info
  		if (p.hasSecondaryHeader()) {
  
! 			// secondary time stamp only valid in in first or standalone
! 			// packets...
  			if (getFirstTime() == 0L) {
! 				// System.out.println("Here...");
  				setFirstTime(p.getTimeStamp(8));
  			}
! 
  			setLastTime(p.getTimeStamp(8));
  		}
! 
! 		// System.out.println("CRIS Add packet");
  		Packet pcopy = CopyPacket.deep(p, packetPool);
! 
  		getPacketList().add(pcopy);
  
  	}
! 
  	/**
! 	 * Write the ATMSRawApplication structure to the given HDF file specified by
! 	 * the HDF input handle
! 	 * 
! 	 * @param hdfFile
! 	 *            input handle to a previous opened HDF file
  	 * @return true if the write succeeds
! 	 * @throws RtStpsException
! 	 *             Wraps HDF exceptions
  	 */
  	@Override
  	public boolean write(int hdfFile) throws RtStpsException {
  		boolean ret = false;
  		if (this.scanCount < this.scansPerGranule) {
  			if (stats == null) {
! 				System.out.println("Deleting partial ATMS Granule -- ["
! 						+ this.scanCount + "] scans, collected packets ["
! 						+ this.sciPacketCount + "]");
  			} else {
  				stats.sci_discardedGranules.value++;
! 			}
  			ret = false;
  		} else {
  			if (stats == null) {
! 				System.out.println("Creating ATMS granule of ["
! 						+ this.scanCount + "] scans");
  			} else {
  				stats.sci_createdGranules.value++;
  			}
  			super.write(hdfFile);
  			ret = true;
! 
  		}
! 
! 		System.out.println("ATMS Sci packets in granule: " + sciPacketCount
! 				+ " Packet per scan: " + (float) sciPacketCount
! 				/ (float) scansPerGranule);
! 		System.out.println("ATMS app ids = "
! 				+ super.appIdCountersToString(scansPerGranule));
  		scanCount = -1;
! 
  		sciPacketCount = 0;
  
  		return ret;
  	}
  
  	/**
! 	 * Close out the RawApplicationPacket which writes the results to the HDF
! 	 * file and cleans up.
  	 */
  	public void close() throws RtStpsException {
  		super.close();
! 
  		scanCount = -1;
! 
  		sciPacketCount = 0;
  	}
  
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/ATMSRawApplicationPackets.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 83,88 ****
--- 83,89 ----
  	 * @throws RtStpsException Wraps any HDF exception
  	 */
  	public boolean notFull(Packet p) throws RtStpsException {
+ 		System.out.println("ATMS not full1");
  
  		if (scanState == ATMSScanState.Complete) {
  			return false;  // FULL
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/CRISRawApplicationPackets2.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/CRISRawApplicationPackets2.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/CRISRawApplicationPackets2.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/CRISRawApplicationPackets2.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 2,161 ****
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
! */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
- 
- 
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
  import gov.nasa.gsfc.drl.rtstps.core.ccsds.Packet;
  import ncsa.hdf.hdf5lib.exceptions.HDF5LibraryException;
  
  /**
!  * Build CrIS [@link RawApplicationPackets} by capturing groups scan packets between packet with
!  * and application ID of 1289.  The first group captured is likely going to be short due
!  * to the fact that frame lock could occur at any time.  Scans groups that form a granule are specified
!  * externally in the constructor.
   * 
   * Current
!  *
   */
  public class CRISRawApplicationPackets2 extends RawApplicationPackets {
  	private final int scansPerGranule = 4; // approx x secs worth
  	private Stats stats = null;
! 	private int scanCount = -1;  // FIXME also likely a bug
  	private int sciPacketCount = 0;
! 	
  	/**
  	 * Constructor to initialize the RawApplicationPackets algorithm for CrIS.
! 	 * @param satellite the satellite ID as defined by the mission documents
! 	 * @param setNum the set number which is appended to the end of each RawApplicationPacket in the HDF
! 	 * @param scansPerGranule The number of scans to collect to make one granule
  	 */
! 	public CRISRawApplicationPackets2(SpacecraftId satellite, int setNum, int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.CrIS_Science, setNum, packetPool);
! 		
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
! 		
! 		
! 		
  	}
! 	
! 	public CRISRawApplicationPackets2(Stats stats, SpacecraftId satellite, int setNum, int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.CrIS_Science, setNum, packetPool);
! 		
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
! 		
! 	
  		this.stats = stats;
  	}
  
- 	
- 	
  	/**
! 	 * Constructor which attempts to read the RawApplicationPacket entry that pre-exists.
! 	 * The contents of the dataspace are read into a memory buffer... assuming it will fit.
! 	 * @param allRDRId  the rdrAll Groups id
! 	 * @param setNum the set number of raw entry
! 	 * @throws RtStpsException 
! 	 * @throws NullPointerException 
! 	 * @throws HDF5LibraryException 
  	 */
! 	public CRISRawApplicationPackets2(int allRDRId, int setNum) throws RtStpsException {
  		super(allRDRId, setNum);
  	}
! 	
! 	public CRISRawApplicationPackets2(int readId, int setNum, boolean usedByGranuleOnly) throws RtStpsException {
  		super(readId, setNum, true);
  	}
  
  	/**
! 	 * Granules are created from scans.  Scans in CrIS are lots of packets but the 8 second
! 	 * packet <b>seems</b> to indicate the start of a scan.   We collect it and everything after it
! 	 * as one scan until it re-appears.  Anything more complex than this can be built on top of this
! 	 * one assumption.
! 	 * 
! 	 * @param p  a Packet to be put into the CrIS RawApplicationPackets area
! 	 * @return true if it can be put there, or false if it is full and should be written to disk first
! 	 * @exception wraps any HDF exceptions in RtStpsException
  	 */
  	public boolean notFull(Packet p) throws RtStpsException {
! 		
  		// every appearance of 1289 means start of scan
! 		
! 		if (p.isStandalonePacket() && p.hasSecondaryHeader()) {
! 			if (p.getApplicationId() == 1289) {
! 				
! 					
! 						++scanCount;
! 					
  			}
  		}
! 		return (scanCount < scansPerGranule);  // true == not full, false == full
! 		
  
  	}
! 	
! 	
! 	
! 	/**
! 	 * Put the packet into the CrISRawApplications area, the method <code>notFull</code> should
! 	 * have been called first to check if this is allowed or not.
! 	 * @param p a Packet to put into it
! 	 * @exception wraps any HDF exceptions in RtStpsException
  	 */
  	public void put(Packet p) throws RtStpsException {
! 		if (scanCount < 0) { // throw away any initial packets if we've not seen the start of a scan...
! 			if (stats == null) {
! 				System.out.println("Trimming CrIS [" + p.getApplicationId() + "]");
! 			} else {
! 				//stats.sci_trimmedPackets.value++;
! 			}
! 			return;
! 		}
  		sciPacketCount++;
! 		
  		this.updateAppIdCounters(p.getApplicationId());
! 		
  		RDRName rdrName = RDRName.fromAppId(p.getApplicationId());
! 		
  		if (rdrName != RDRName.CrIS_Science) {
! 			throw new RtStpsException("Not a CrIS science packet [" + p.getApplicationId() + "]");
  		}
  
  		// collect time info
  		if (p.hasSecondaryHeader()) {
  
! 			// secondary time stamp only valid in in first or standalone packets...
  			if (getFirstTime() == 0L) {
! 				//System.out.println("Here...");
  				setFirstTime(p.getTimeStamp(8));
  			}
! 			
  			setLastTime(p.getTimeStamp(8));
  		}
  		Packet pcopy = CopyPacket.deep(p, packetPool);
  		getPacketList().add(pcopy);
  	}
! 	
  	/**
! 	 * Write the accumulate packets to the RDR/HDF file.  Note that this method
! 	 * must be used in conjunction with method <code>notFull</code> and <code>put</code>.
! 	 * @param hdfFile the handle to the RDR/HDF file that the packets should written to
  	 * @return true if the write succeeded
! 	 * @exception wraps any HDF exceptions in RtStpsException
  	 */
! 	public boolean write(int hdfFile) throws RtStpsException  {
! 		
  		boolean ret = true;
  		if (this.scanCount < this.scansPerGranule) {
  
  			if (stats == null) {
! 				System.out.println("Deleting partial CrIS Granule -- [" + scanCount + "] scans");
  			} else {
  				stats.sci_discardedGranules.value++;
  			}
--- 2,246 ----
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
!  */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
  import gov.nasa.gsfc.drl.rtstps.core.ccsds.Packet;
  import ncsa.hdf.hdf5lib.exceptions.HDF5LibraryException;
  
  /**
!  * Build CrIS [@link RawApplicationPackets} by capturing groups scan packets
!  * between packet with and application ID of 1289. The first group captured is
!  * likely going to be short due to the fact that frame lock could occur at any
!  * time. Scans groups that form a granule are specified externally in the
!  * constructor.
   * 
   * Current
!  * 
   */
  public class CRISRawApplicationPackets2 extends RawApplicationPackets {
  	private final int scansPerGranule = 4; // approx x secs worth
  	private Stats stats = null;
! 	private int scanCount = -1; // FIXME also likely a bug
  	private int sciPacketCount = 0;
! 
  	/**
  	 * Constructor to initialize the RawApplicationPackets algorithm for CrIS.
! 	 * 
! 	 * @param satellite
! 	 *            the satellite ID as defined by the mission documents
! 	 * @param setNum
! 	 *            the set number which is appended to the end of each
! 	 *            RawApplicationPacket in the HDF
! 	 * @param scansPerGranule
! 	 *            The number of scans to collect to make one granule
  	 */
! 	public CRISRawApplicationPackets2(SpacecraftId satellite, int setNum,
! 			int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.CrIS_Science, setNum, packetPool);
! 
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
! 
  	}
! 
! 	public CRISRawApplicationPackets2(Stats stats, SpacecraftId satellite,
! 			int setNum, int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.CrIS_Science, setNum, packetPool);
! 
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
! 
  		this.stats = stats;
  	}
  
  	/**
! 	 * Constructor which attempts to read the RawApplicationPacket entry that
! 	 * pre-exists. The contents of the dataspace are read into a memory
! 	 * buffer... assuming it will fit.
! 	 * 
! 	 * @param allRDRId
! 	 *            the rdrAll Groups id
! 	 * @param setNum
! 	 *            the set number of raw entry
! 	 * @throws RtStpsException
! 	 * @throws NullPointerException
! 	 * @throws HDF5LibraryException
  	 */
! 	public CRISRawApplicationPackets2(int allRDRId, int setNum)
! 			throws RtStpsException {
  		super(allRDRId, setNum);
  	}
! 
! 	public CRISRawApplicationPackets2(int readId, int setNum,
! 			boolean usedByGranuleOnly) throws RtStpsException {
  		super(readId, setNum, true);
  	}
  
+ 	private static long firstTime = 0;
+ 
+ 	// /**
+ 	// * Granules are created from scans. Scans in CrIS are lots of packets but
+ 	// the 8 second
+ 	// * packet <b>seems</b> to indicate the start of a scan. We collect it and
+ 	// everything after it
+ 	// * as one scan until it re-appears. Anything more complex than this can be
+ 	// built on top of this
+ 	// * one assumption.
+ 	// *
+ 	// * @param p a Packet to be put into the CrIS RawApplicationPackets area
+ 	// * @return true if it can be put there, or false if it is full and should
+ 	// be written to disk first
+ 	// * @exception wraps any HDF exceptions in RtStpsException
+ 	// */
+ 	// public boolean notFull(Packet p) throws RtStpsException {
+ 	//
+ 	// // every appearance of 1289 means start of scan
+ 	//
+ 	// if (p.isStandalonePacket() && p.hasSecondaryHeader()) {
+ 	// if (p.getApplicationId() == 1289) {
+ 	//
+ 	//
+ 	// ++scanCount;
+ 	//
+ 	// }
+ 	// }
+ 	// return (scanCount < scansPerGranule); // true == not full, false == full
+ 	//
+ 	//
+ 	// }
  	/**
! 	 * Granules are created from scans. Scans in CrIS are lots of packets but
! 	 * the 8 second packet <b>seems</b> to indicate the start of a scan. We
! 	 * collect it and everything after it as one scan until it re-appears.
! 	 * Anything more complex than this can be built on top of this one
! 	 * assumption.
! 	 * 
! 	 * @param p
! 	 *            a Packet to be put into the CrIS RawApplicationPackets area
! 	 * @return true if it can be put there, or false if it is full and should be
! 	 *         written to disk first
! 	 * @exception wraps
! 	 *                any HDF exceptions in RtStpsException
  	 */
  	public boolean notFull(Packet p) throws RtStpsException {
! 
  		// every appearance of 1289 means start of scan
! 		boolean notFull = true;
! 
! 		long timestamp = p.getTimeStamp(8);
! 
! 		GranuleId currentGranId = new GranuleId(SpacecraftId.npp,
! 				p.getTimeStamp(8),  RDRName.CrIS_Science);
! 
! 		// System.out.printf("VIIRS: Gran %s seq %d ts %d obs %d \n",
! 		// currentGranId.toString(), p.getSequenceCounter(),
! 		// timestamp, obsTime.getMicrosSinceEpoch());
! 
! 		if (currentGranId.toString().startsWith("NPP-") == false) {
! 
! 			if (CRISRawApplicationPackets2.firstTime < 0l) {
! 				CRISRawApplicationPackets2.firstTime = timestamp;
! 				setFirstTime(timestamp);
! 				scanCount=0;
! 			} else {
! 				GranuleId startGranId = new GranuleId(SpacecraftId.npp,
! 						getFirstTime(),  RDRName.CrIS_Science);
! 
! 				if (startGranId.toString().contentEquals(
! 						currentGranId.toString()) == false) {
! 					firstTime = -1;
! 					System.out.println("CRIS: " + startGranId.toString()
! 							+ " Current:" + currentGranId.toString());
! 
! 					notFull = false; // if 20secs have gone by, the granule
! 
! 				}
! 				else
! 				{
! 					scanCount++;
! 					setLastTime(timestamp);
! 				}
  			}
  		}
! 
! 		return notFull;
  
  	}
! 
! 	/**
! 	 * Put the packet into the CrISRawApplications area, the method
! 	 * <code>notFull</code> should have been called first to check if this is
! 	 * allowed or not.
! 	 * 
! 	 * @param p
! 	 *            a Packet to put into it
! 	 * @exception wraps
! 	 *                any HDF exceptions in RtStpsException
  	 */
  	public void put(Packet p) throws RtStpsException {
! //		if (scanCount < 0) { // throw away any initial packets if we've not seen
! //								// the start of a scan...
! //			if (stats == null) {
! //				System.out.println("Trimming CrIS [" + p.getApplicationId()
! //						+ "]");
! //			} else {
! //				// stats.sci_trimmedPackets.value++;
! //			}
! //			return;
! //		}
  		sciPacketCount++;
! 
  		this.updateAppIdCounters(p.getApplicationId());
! 
  		RDRName rdrName = RDRName.fromAppId(p.getApplicationId());
! 
  		if (rdrName != RDRName.CrIS_Science) {
! 			throw new RtStpsException("Not a CrIS science packet ["
! 					+ p.getApplicationId() + "]");
  		}
  
  		// collect time info
  		if (p.hasSecondaryHeader()) {
  
! 			// secondary time stamp only valid in in first or standalone
! 			// packets...
  			if (getFirstTime() == 0L) {
! 				// System.out.println("Here...");
  				setFirstTime(p.getTimeStamp(8));
  			}
! 
  			setLastTime(p.getTimeStamp(8));
  		}
+ //		System.out.println("ATMS Add packet");
+ 
  		Packet pcopy = CopyPacket.deep(p, packetPool);
  		getPacketList().add(pcopy);
  	}
! 
  	/**
! 	 * Write the accumulate packets to the RDR/HDF file. Note that this method
! 	 * must be used in conjunction with method <code>notFull</code> and
! 	 * <code>put</code>.
! 	 * 
! 	 * @param hdfFile
! 	 *            the handle to the RDR/HDF file that the packets should written
! 	 *            to
  	 * @return true if the write succeeded
! 	 * @exception wraps
! 	 *                any HDF exceptions in RtStpsException
  	 */
! 	public boolean write(int hdfFile) throws RtStpsException {
! 
  		boolean ret = true;
  		if (this.scanCount < this.scansPerGranule) {
  
  			if (stats == null) {
! 				System.out.println("Deleting partial CrIS Granule -- ["
! 						+ scanCount + "] scans");
  			} else {
  				stats.sci_discardedGranules.value++;
  			}
***************
*** 164,197 ****
  		} else {
  
  			if (stats == null) {
! 				System.out.println("Creating CrIS Granule with [" + scanCount + "] scans");
  			} else {
  				stats.sci_createdGranules.value++;
  			}
  
  			ret = super.write(hdfFile);
  		}
! 		
! 		System.out.println("CrIS Sci packets in granule: " + sciPacketCount + " Packets per scan: " + (float)sciPacketCount / (float)scansPerGranule);
! 		System.out.println("CrIS app ids = " + super.appIdCountersToString(scansPerGranule));
  		scanCount = -1;
! 		
  		sciPacketCount = 0;
! 		
  		return ret;
  	}
  
  	/**
! 	 * Close the RDR/HDF file specifically for the RawApplicationsPackets.  This method should be 
! 	 * called once specific RawApplicationPacket_x has been written. 
! 	 * @exception wraps any HDF exceptions in RtStpsException
  	 */
! 	public void close() throws RtStpsException  {
  		super.close();
  		scanCount = -1;
! 		
  		sciPacketCount = 0;
  	}
  
- 
  }
--- 249,288 ----
  		} else {
  
  			if (stats == null) {
! 				System.out.println("Creating CrIS Granule with [" + scanCount
! 						+ "] scans");
  			} else {
  				stats.sci_createdGranules.value++;
  			}
  
  			ret = super.write(hdfFile);
  		}
! 
! 		System.out.println("CrIS Sci packets in granule: " + sciPacketCount
! 				+ " Packets per scan: " + (float) sciPacketCount
! 				/ (float) scansPerGranule);
! 		System.out.println("CrIS app ids = "
! 				+ super.appIdCountersToString(scansPerGranule));
  		scanCount = -1;
! 
  		sciPacketCount = 0;
! 
  		return ret;
  	}
  
  	/**
! 	 * Close the RDR/HDF file specifically for the RawApplicationsPackets. This
! 	 * method should be called once specific RawApplicationPacket_x has been
! 	 * written.
! 	 * 
! 	 * @exception wraps
! 	 *                any HDF exceptions in RtStpsException
  	 */
! 	public void close() throws RtStpsException {
  		super.close();
  		scanCount = -1;
! 
  		sciPacketCount = 0;
  	}
  
  }
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/GranuleId.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/GranuleId.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/GranuleId.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/GranuleId.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 2,102 ****
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
! */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
- 
  /**
!  * A Granule identifier is a way of calculating a unique identifier for the IDPS system.  It is specified as part of
!  * RDR attributes for granules in the specifications.   This implements the formula.   One item the firstAscendingNodeAfterLaunch is
!  * currenlty not known.
   * 
   * 
-  *
   */
  public class GranuleId {
  	private String name;
! 	
  	// FIXME this is hack for now until this gets defined better...
! 	//public static PDSDate  firstAscendingNodeAfterLaunch = new PDSDate(1958, 0, 1, 0, 0, 0, 0, 0); // new PDSDate(2009, 0, 25, 0, 0, 0, 0, 0);
! 	public static PDSDate  firstAscendingNodeAfterLaunch = new PDSDate(2011, 10, 28, 10, 50, 0, 0, 0); // new PDSDate(2009, 0, 25, 0, 0, 0, 0, 0);
  
  	/**
! 	 * Use only for the case of reading the ID from the attributes in an HDF file
  	 * @param granuleIdStr
  	 */
  	public GranuleId(String granuleIdStr) {
  		this.name = granuleIdStr;
  	}
! 	
  	/**
  	 * Build a granuleId from various inputs
! 	 * @param spacecraftId the spacecraft identifier
! 	 * @param pktObservationTime the observation time of the packet
! 	 * @param firstAscendingNodeAfterLaunch the first ascending now after launch (currently not known)
! 	 * @param granuleSizeInTime the granule size in time, this would be time span from first and last packets in the granule in microseconds 
! 	 */
! 	public GranuleId(SpacecraftId spacecraftId, PDSDate pktObservationTime, PDSDate firstAscendingNodeAfterLaunch, long granuleSizeInTime) {
! 		name = String.format("%s%012d", spacecraftId.toString(), granuleIDValue(pktObservationTime, GranuleId.firstAscendingNodeAfterLaunch, granuleSizeInTime) );
  	}
! 	
  	/**
! 	 * Build a granule ID from various inputs, most importantly the times are in 64-bit quantities
! 	 * @param spacecraftId the spacecraft identifier
! 	 * @param pktObservationTime the packet observation time in microseconds
! 	 * @param firstAscendingNodeAfterLaunch the first ascending node after launch (currently unknown)
! 	 * @param granuleSizeInTime the granule size in time (microseconds)
! 	 */
! 	public GranuleId(SpacecraftId spacecraftId, long pktObservationTime, long firstAscendingNodeAfterLaunch, long granuleSizeInTime) {
! 		PDSDate obsTime = new PDSDate(pktObservationTime);
! 		PDSDate fanLaunchTime = new PDSDate(firstAscendingNodeAfterLaunch);
  		
! 		name = String.format("%s%012d", spacecraftId.toString(), granuleIDValue(obsTime, GranuleId.firstAscendingNodeAfterLaunch, granuleSizeInTime) );
  	}
! 	
  	/**
  	 * This implements the formula, taking from the JPSS documentation
! 	 * @param pktObservationTime the packet observation time in microseconds
! 	 * @param firstAscendingNodeAfterLaunch the first ascending node after launch (currently unknown)
! 	 * @param granuleSizeInTime the first ascending node after launch (currently unknown)
  	 * @return the calculated identifier as an <code>long</code>
  	 */
! 	private long granuleIDValue(long pktObservationTime, long firstAscendingNodeAfterLaunch, long granuleSizeInTime) {
! 		
! 		long numberG = (pktObservationTime - firstAscendingNodeAfterLaunch ) / granuleSizeInTime;  // floor
! 		long granuleStartTime = numberG * granuleSizeInTime + firstAscendingNodeAfterLaunch;
! 		long granuleEndTime = granuleStartTime + granuleSizeInTime;
! 		long granuleIDValue = (numberG * granuleSizeInTime ) / 100000L; // 10^5;
! 		
! 		//System.out.println("GranuleIDValue = " + granuleIDValue);
  		return granuleIDValue;
  	}
  
- 	
  	/**
! 	 * This implements the formula, taking from the JPSS documentation but uses {@link PDSDate} as inputs
! 	 * @param pktObservationTime the packet observation time as a <code>PDSDate</code>
! 	 * @param firstAscendingNodeAfterLaunch the first ascending node after launch (currently unknown) as a <code>PDSDate</code>
! 	 * @param granuleSizeInTime the first ascending node after launch (currently unknown)
  	 * @return the calculated identifier as an <code>long</code>
  	 */
! 	private long granuleIDValue(PDSDate pktObservationTime, PDSDate firstAscendingNodeAfterLaunch, long granuleSizeInTime) {
! 		//System.out.println("obsTime: "  + pktObservationTime.toString());
! 		
! 		//System.out.println("firstAscendingNodeAfterLaunch: "  + firstAscendingNodeAfterLaunch.toString());
! 		
! 		//System.out.println("GranuleSizeInTime: " + granuleSizeInTime);
! 		
  
- 		
- 		return this.granuleIDValue(pktObservationTime.getMicrosSinceEpoch(), 
- 							firstAscendingNodeAfterLaunch.getMicrosSinceEpoch(), 
- 							granuleSizeInTime); 
- 		
  	}
! 	
  	/**
  	 * Return the GranuleId in a <code>String</code>
  	 * @return a string with the granule identifier
  	 */
  	public String toString() {
--- 2,215 ----
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
!  */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
  /**
!  * A Granule identifier is a way of calculating a unique identifier for the IDPS
!  * system. It is specified as part of RDR attributes for granules in the
!  * specifications. This implements the formula. One item the
!  * firstAscendingNodeAfterLaunch is currenlty not known.
!  * 
   * 
   * 
   */
  public class GranuleId {
  	private String name;
! 
  	// FIXME this is hack for now until this gets defined better...
! 	// public static PDSDate firstAscendingNodeAfterLaunch = new PDSDate(1958,
! 	// 0, 1, 0, 0, 0, 0, 0); // new PDSDate(2009, 0, 25, 0, 0, 0, 0, 0);
! 	public static PDSDate firstAscendingNodeAfterLaunch = new PDSDate(2011, 10,
! 			28, 10, 50, 0, 0, 0); // new PDSDate(2009, 0, 25, 0, 0, 0, 0, 0);
! 	// public static Long FirstTimeAscend=1300968033000000L; // preflight
! 	public static Long FirstTimeAscend = 1698019234000000L; // flight // SSEC
! 															// SRM 2/2/2012
! 
! 	public final static long NPP_SPACECRAFT_DIARY_GRANULE_SIZE = 20000000;
! 	public final static long NPP_VIIRS_SCIENCE_GRANULE_SIZE = 85350000;
! 	public final static long NPP_CRIS_SCIENCE_GRANULE_SIZE = 31997000;
! 	public final static long NPP_ATMS_SCIENCE_GRANULE_SIZE = 31997000;
  
  	/**
! 	 * Use only for the case of reading the ID from the attributes in an HDF
! 	 * file
! 	 * 
  	 * @param granuleIdStr
  	 */
  	public GranuleId(String granuleIdStr) {
  		this.name = granuleIdStr;
  	}
! 
  	/**
  	 * Build a granuleId from various inputs
! 	 * 
! 	 * @param spacecraftId
! 	 *            the spacecraft identifier
! 	 * @param pktObservationTime
! 	 *            the observation time of the packet
! 	 * @param firstAscendingNodeAfterLaunch
! 	 *            the first ascending now after launch (currently not known)
! 	 * @param granuleSizeInTime
! 	 *            the granule size in time, this would be time span from first
! 	 *            and last packets in the granule in microseconds
! 	 */
! 	public GranuleId(SpacecraftId spacecraftId, PDSDate pktObservationTime,
! 			RDRName rdrName) {
! 		name = String.format("%s%012d", spacecraftId.toString(),
! 				granuleIDValue(pktObservationTime, rdrName));
  	}
! 
  	/**
! 	 * Build a granule ID from various inputs, most importantly the times are in
! 	 * 64-bit quantities
! 	 * 
! 	 * @param spacecraftId
! 	 *            the spacecraft identifier
! 	 * @param pktObservationTime
! 	 *            the packet observation time in microseconds
! 	 * @param firstAscendingNodeAfterLaunch
! 	 *            the first ascending node after launch (currently unknown)
! 	 * @param granuleSizeInTime
! 	 *            the granule size in time (microseconds)
! 	 */
! 	public GranuleId(SpacecraftId spacecraftId, long pktObservationTime,
! 			RDRName rdrName) {
! 
! 		// PDSDate obsTime = new PDSDate(pktObservationTime);
! 		LeapDate obsTime = new LeapDate(pktObservationTime); // srm
! 
! 	
! 
! 		
  		
! 		name = String.format("%s%012d", spacecraftId.toString(),
! 				granuleIDValue(obsTime, rdrName));
  	}
! 
! 	// FIXME: SSEC - calculating start and end times based on granule
! 	// boundaries, not packet times
! 	public static long getGranuleSize(RDRName myRdrName) {
! 		// FIXME: times should come from table (ideally derived from
! 		// INF_CFG.xml)
! 		if (myRdrName == RDRName.VIIRS_Science) {
! 			return 85350000;
! 		} else if (myRdrName == RDRName.ATMS_Science) {
! 			return 31997000;
! 		} else if (myRdrName == RDRName.CrIS_Science) {
! 			return 31997000;
! 		} else if (myRdrName == RDRName.NPP_Ephemeris_and_Attitude) {
! 			return 20000000;
! 
! 			// FIXME: need to handle other packet types
! 		} else {
! 			System.out.println("getGranuleSize() error: unknown RDR name "
! 					+ myRdrName);
! 			System.exit(-1);
! 			return -1;
! 		}
! 	}
! 
! 	// Copied from GranuleID.java, but should only be done in one place. Can use
! 	// time of any packet in
! 	// granule for this calculation.
! 	public static long calcGranuleStartTime(long ietTime, RDRName myRdrName) {
! 		long granuleSizeInTime = getGranuleSize(myRdrName);
! 		long FirstTimeAscend = 1698019234000000L;
! 		long numberG = (ietTime - FirstTimeAscend) / granuleSizeInTime; // floor
! 		return numberG * granuleSizeInTime + FirstTimeAscend;
! 	}
! 
! 	public static long calcGranuleEndTime(long ietTime, RDRName myRdrName) {
! 		long granuleSizeInTime = getGranuleSize(myRdrName);
! 		return calcGranuleStartTime(ietTime, myRdrName) + granuleSizeInTime;
! 	}
! 
! 	// /**
! 	// * This implements the formula, taking from the JPSS documentation
! 	// * @param pktObservationTime the packet observation time in microseconds
! 	// * @param firstAscendingNodeAfterLaunch the first ascending node after
! 	// launch (currently unknown)
! 	// * @param granuleSizeInTime the first ascending node after launch
! 	// (currently unknown)
! 	// * @return the calculated identifier as an <code>long</code>
! 	// */
! 	// private long granuleIDValue(long pktObservationTime, long
! 	// firstAscendingNodeAfterLaunch, long granuleSizeInTime) {
! 	// firstAscendingNodeAfterLaunch = FirstTimeAscend; // SSEC SRM 2/2/2012
! 	//
! 	// long numberG = (pktObservationTime - firstAscendingNodeAfterLaunch ) /
! 	// granuleSizeInTime; // floor
! 	// long granuleStartTime = numberG * granuleSizeInTime +
! 	// firstAscendingNodeAfterLaunch;
! 	// long granuleEndTime = granuleStartTime + granuleSizeInTime;
! 	// long granuleIDValue = (numberG * granuleSizeInTime ) / 100000L; // 10^5;
! 	//
! 	// //System.out.println("GranuleIDValue = " + granuleIDValue);
! 	// return granuleIDValue;
! 	// }
  	/**
  	 * This implements the formula, taking from the JPSS documentation
! 	 * 
! 	 * @param pktObservationTime
! 	 *            the packet observation time in microseconds
! 	 * @param firstAscendingNodeAfterLaunch
! 	 *            the first ascending node after launch (currently unknown)
! 	 * @param granuleSizeInTime
! 	 *            the first ascending node after launch (currently unknown)
  	 * @return the calculated identifier as an <code>long</code>
  	 */
! 	private long granuleIDValue(long pktObservationTime, RDRName rdrName) {
! 
! 		long firstAscendingNodeAfterLaunch = FirstTimeAscend;
! 		long granuleSizeInTime = getGranuleSize(rdrName);
! 		long numberG = (pktObservationTime - firstAscendingNodeAfterLaunch)
! 				/ granuleSizeInTime; // floor
! 		// long granuleStartTime = numberG * granuleSizeInTime +
! 		// firstAscendingNodeAfterLaunch;
! 		// long granuleEndTime = granuleStartTime + granuleSizeInTime;
! 
! 		long granuleIDValue = (numberG * granuleSizeInTime) / 100000L; // 10^5;
! 
! 		//
! 		// System.out.println("GranuleIDValue = " + granuleIDValue
! 		// + " pktObservationTime = " + pktObservationTime + " "
! 		// + granuleSizeInTime + " delta " + delta + " fa "
! 		// + FirstTimeAscend + " " + firstAscendingNodeAfterLaunch + " "
! 		// + isSpace);
! 
  		return granuleIDValue;
  	}
  
  	/**
! 	 * This implements the formula, taking from the JPSS documentation but uses
! 	 * {@link PDSDate} as inputs
! 	 * 
! 	 * @param pktObservationTime
! 	 *            the packet observation time as a <code>PDSDate</code>
! 	 * @param firstAscendingNodeAfterLaunch
! 	 *            the first ascending node after launch (currently unknown) as a
! 	 *            <code>PDSDate</code>
! 	 * @param granuleSizeInTime
! 	 *            the first ascending node after launch (currently unknown)
  	 * @return the calculated identifier as an <code>long</code>
  	 */
! 	private long granuleIDValue(PDSDate pktObservationTime, RDRName rdrName) {
! 		// System.out.println("obsTime: " + pktObservationTime.toString());
! 
! 		// System.out.println("firstAscendingNodeAfterLaunch: " +
! 		// firstAscendingNodeAfterLaunch.toString());
! 
! 		// System.out.println("GranuleSizeInTime: " + granuleSizeInTime);
! 
! 		return this.granuleIDValue(pktObservationTime.getMicrosSinceEpoch(),
! 				rdrName);
  
  	}
! 
  	/**
  	 * Return the GranuleId in a <code>String</code>
+ 	 * 
  	 * @return a string with the granule identifier
  	 */
  	public String toString() {
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RawApplicationPackets.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RawApplicationPackets.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RawApplicationPackets.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RawApplicationPackets.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 226,231 ****
--- 226,236 ----
  	    // Create the data space with unlimited dimensions
  		try {
  			dataSpace = H5.H5Screate_simple (1, totalDims, null);
+ 			
+ 			long     offset[] = new long[1];                                                                // SSEC SRM 2/2/2012
+ 			offset[0]=0; 											// SSEC SRM 2/2/2012
+ 			H5.H5Sselect_hyperslab (dataSpace, HDF5Constants.H5S_SELECT_SET, offset, null, totalDims, null); // SSEC SRM 2/2/2012  
+ 
  		} catch (HDF5Exception e) {
  			throw new RtStpsException(e);
  		}  
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRAppIdItem.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRAppIdItem.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRAppIdItem.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRAppIdItem.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 40,46 ****
  		 * @param pktTrackerIndex the packet tracker index
  		 * @param pktsReceived the packets received
  		 */
! 		public RDRAppIdItem(RDRName rdrName, PacketName packetName, int pktTrackerIndex, int pktsReceived) {
  			this.rdrName = rdrName;
  			this.packetName = packetName;
  			this.name = packetName.toString();
--- 40,46 ----
  		 * @param pktTrackerIndex the packet tracker index
  		 * @param pktsReceived the packets received
  		 */
! 		public RDRAppIdItem(RDRName rdrName, PacketName packetName, int pktTrackerIndex, int pktsReceived, int nextIndex) {
  			this.rdrName = rdrName;
  			this.packetName = packetName;
  			this.name = packetName.toString();
***************
*** 59,64 ****
--- 59,71 ----
  			this.pktsReserved = reserved;
  			//}
  			
+ 			System.out.printf("Packets index %d rec %d next %d \n", pktTrackerIndex,  pktsReceived,  nextIndex);
+ //			this.pktsReserved = pktsReceived;  // srm
+ 
+ 			if ( reserved == 0 ){
+ 				System.out.println("Set reserved");this.pktsReserved = pktsReceived;
+ 			}
+ 			
  			//this.pktsReserved = pktsReceived;
  			this.pktsReceived = pktsReceived;
  			
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRAppIdList.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRAppIdList.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRAppIdList.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRAppIdList.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 52,64 ****
  			this.appIdCount[p.getApplicationId()] += 1;
  		}
  		
! 		// build the AppIdItem list
  		Iterator<PacketName> pni = packetNames.iterator();
  		
  		while (pni.hasNext()) {
  			PacketName packetName = pni.next();
  			int appId = packetName.getAppId();
! 			RDRAppIdItem rdrItem = new RDRAppIdItem(rdrName, packetName, packetTrackerIndex(appId, packetTracker), this.appIdCount[appId]);
  			
  			rdrAppIdList.add(rdrItem);
  		}
--- 52,79 ----
  			this.appIdCount[p.getApplicationId()] += 1;
  		}
  		
! 		int[] trackerIndex = new int[packetNames.size()+1];
! 		// build quick look ahead array
  		Iterator<PacketName> pni = packetNames.iterator();
+ 		int trackIn=0;
+ 		while (pni.hasNext()) {
+ 			PacketName packetName = pni.next();
+ 			int appId = packetName.getAppId();
+ 			trackerIndex[trackIn]= packetTrackerIndex(appId, packetTracker);
+ 			trackIn++;
+ 		}
  		
+ 		// build the AppIdItem list
+ //		Iterator<PacketName>
+ 		pni = packetNames.iterator();
+ 		int index=1;
  		while (pni.hasNext()) {
  			PacketName packetName = pni.next();
+ 			
+ 			
  			int appId = packetName.getAppId();
! 			RDRAppIdItem rdrItem = new RDRAppIdItem(rdrName, packetName, packetTrackerIndex(appId, packetTracker), this.appIdCount[appId],trackerIndex[index]);
! 			index++;
  			
  			rdrAppIdList.add(rdrItem);
  		}
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRFileWriter.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRFileWriter.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRFileWriter.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDRFileWriter.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 2,12 ****
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
! */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
- 
- 
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
  import gov.nasa.gsfc.drl.rtstps.core.ccsds.Packet;
  
--- 2,10 ----
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
!  */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
  import gov.nasa.gsfc.drl.rtstps.core.ccsds.Packet;
  
***************
*** 16,46 ****
  import java.util.List;
  import java.util.UUID;
  
- 
- 
  public class RDRFileWriter {
! 	
  	private String tempFilename;
  	private String destPath;
! 	
  	// private List<RDRProduct> rdrProducts = new LinkedList<RDRProduct>();
  	private RDRCreateFile rdrFile;
! 	
! 	
  	private int orbit;
  	private Origin distributor;
  	private MissionName missionName;
  	private Origin datasetSource;
  	private PlatformShortName platformShortname;
! 	
! 	
! 	public RDRFileWriter(String destPath, 
! 						int orbit, 
! 						int rdrCount, 
! 						Origin distributor, 
! 						MissionName missionName, 
! 						Origin datasetSource, 
! 						PlatformShortName platformShortname) throws RtStpsException {
  		this.distributor = distributor;
  		this.missionName = missionName;
  		this.datasetSource = datasetSource;
--- 14,36 ----
  import java.util.List;
  import java.util.UUID;
  
  public class RDRFileWriter {
! 
  	private String tempFilename;
  	private String destPath;
! 
  	// private List<RDRProduct> rdrProducts = new LinkedList<RDRProduct>();
  	private RDRCreateFile rdrFile;
! 
  	private int orbit;
  	private Origin distributor;
  	private MissionName missionName;
  	private Origin datasetSource;
  	private PlatformShortName platformShortname;
! 
! 	public RDRFileWriter(String destPath, int orbit, int rdrCount,
! 			Origin distributor, MissionName missionName, Origin datasetSource,
! 			PlatformShortName platformShortname) throws RtStpsException {
  		this.distributor = distributor;
  		this.missionName = missionName;
  		this.datasetSource = datasetSource;
***************
*** 48,67 ****
  		this.orbit = orbit;
  		this.destPath = destPath;
  		tempFilename = UUID.randomUUID().toString() + ".h5";
! 			
  		rdrFile = new RDRCreateFile(destPath, tempFilename, rdrCount);
  	}
! 	
! 	
! 	public RDRFileWriter(Stats stats, 
! 			String destPath, 
! 			int orbit, 
! 			int rdrCount, 
! 			Origin distributor, 
! 			MissionName missionName, 
! 			Origin datasetSource, 
  			PlatformShortName platformShortname) throws RtStpsException {
! 		
  		this.distributor = distributor;
  		this.missionName = missionName;
  		this.datasetSource = datasetSource;
--- 38,51 ----
  		this.orbit = orbit;
  		this.destPath = destPath;
  		tempFilename = UUID.randomUUID().toString() + ".h5";
! 
  		rdrFile = new RDRCreateFile(destPath, tempFilename, rdrCount);
  	}
! 
! 	public RDRFileWriter(Stats stats, String destPath, int orbit, int rdrCount,
! 			Origin distributor, MissionName missionName, Origin datasetSource,
  			PlatformShortName platformShortname) throws RtStpsException {
! 
  		this.distributor = distributor;
  		this.missionName = missionName;
  		this.datasetSource = datasetSource;
***************
*** 73,176 ****
  		rdrFile = new RDRCreateFile(stats, destPath, tempFilename, rdrCount);
  	}
  
- 
  	public void put(Packet p) throws RtStpsException {
  		rdrFile.put(p);
  	}
  
- 
  	public void close(boolean hdfCleanup) throws RtStpsException {
! 		
  		Date creationDateAndTime = new Date();
  		// the top level attributes
  		writeAttributes(creationDateAndTime);
! 		
  		// close the rdr file...
  		rdrFile.close();
! 		
  		// clean up any leftover housekeeping
  		if (hdfCleanup) {
  			HDF5Util.cleanup();
  		}
! 		
  		// rename to the final file name
  		rename(creationDateAndTime);
  	}
- 	
- 	private void writeAttributes(Date creationDateAndTime) throws RtStpsException {
  
! 		rdrFile.writeAttributes(creationDateAndTime, distributor, this.missionName, this.datasetSource, platformShortname);
  
! 	}
  
  
  	private void rename(Date creationDateAndTime) throws RtStpsException {
  		File old = new File(destPath, tempFilename);
! 		
  		List<RDR> rdrs = rdrFile.getRDRs();
! 		//PDSDate d1 = rdrFile.getFirstDateTime();
! 		//PDSDate d2 = rdrFile.getLastDataTime();
! 		
  		Aggregate firstAgg = findFirstScienceWeightedAggregate(rdrs);
! 		
! 		// LPEATE seems to want the original data based times not the rounded/truncated times in the file name
! 		PDSDate temp1 = firstAgg.getBeginningDateTime();
! 		PDSDate d1 = new PDSDate(temp1.getOriginalPacketTime());
! 		
! 		//PDSDate temp2 = firstAgg.getEndingDateTime();
! 		//PDSDate d2 = new PDSDate(temp2.getOriginalPacketTime());
! 		
! 		//PDSDate d1 = firstAgg.getBeginningDateTime();
! 		
! 		// But this one is offset from it and so is not really a LPEATE or LeapDate
! 		// it's the same if you get the original time or not in other words.
! 		// That means we have to substract the leap time from it.
! 		PDSDate d2 = firstAgg.getEndingDateTime();
! 		
! 		
! 		
! 		if (rdrs == null) return;
! 		if (rdrs.size() <= 0) return;
! 		if ((d1 == null) || (d2 == null)) return;
! 		
! 		NPOESSFilename nfn = new NPOESSFilename(rdrs,
! 												d1,
! 												d2,
! 												creationDateAndTime,
! 												SpacecraftId.npp,
! 												orbit,
! 												Origin.nfts);
! 		
! 		String realFilename = nfn.toString();
! 		
! 
! 		File nnew = new File(destPath, realFilename);
! 		
! 		old.renameTo(nnew);
! 		
! 		createUserBlock(nnew);
  	}
- 	
  
  	// FIXME only supports either RDRs with "SCIENCE" in the name or the DIARY
! 	private Aggregate findFirstScienceWeightedAggregate(List<RDR> rdrs) throws RtStpsException {
  		List<RDR> sciRDRs = new LinkedList<RDR>();
  		RDR diaryRDR = null;
  		for (RDR rdr : rdrs) {
! 			String rdrNameStr = rdr.getRDRName().getRDRStringName();  // avoid toString w/RDRName
  			if (rdrNameStr.contains("SCIENCE")) {
  				sciRDRs.add(rdr);
  			} else if (rdrNameStr.contains("DIARY")) {
  				diaryRDR = rdr;
  			} else {
! 				throw new RtStpsException("No support for non-science/non-diary RDRs [" + rdrNameStr + "]");
  			}
  		}
! 		
  		if ((sciRDRs.size() <= 0) && (diaryRDR == null)) {
! 			throw new RtStpsException("No science/diary RDRs found -- unable to get first/last time for filename");			
  		}
! 	
  		Aggregate firstAggregate = null;
  		// if there are any science RDRs, use them...
  		if (sciRDRs.size() > 0) {
--- 57,164 ----
  		rdrFile = new RDRCreateFile(stats, destPath, tempFilename, rdrCount);
  	}
  
  	public void put(Packet p) throws RtStpsException {
  		rdrFile.put(p);
  	}
  
  	public void close(boolean hdfCleanup) throws RtStpsException {
! 
  		Date creationDateAndTime = new Date();
  		// the top level attributes
  		writeAttributes(creationDateAndTime);
! 
  		// close the rdr file...
  		rdrFile.close();
! 
  		// clean up any leftover housekeeping
  		if (hdfCleanup) {
  			HDF5Util.cleanup();
  		}
! 
  		// rename to the final file name
  		rename(creationDateAndTime);
  	}
  
! 	private void writeAttributes(Date creationDateAndTime)
! 			throws RtStpsException {
  
! 		rdrFile.writeAttributes(creationDateAndTime, distributor,
! 				this.missionName, this.datasetSource, platformShortname);
  
+ 	}
  
  	private void rename(Date creationDateAndTime) throws RtStpsException {
  		File old = new File(destPath, tempFilename);
! 
  		List<RDR> rdrs = rdrFile.getRDRs();
! 		// PDSDate d1 = rdrFile.getFirstDateTime();
! 		// PDSDate d2 = rdrFile.getLastDataTime();
! 
  		Aggregate firstAgg = findFirstScienceWeightedAggregate(rdrs);
! 
! 		if (firstAgg != null) {
! 
! 			// LPEATE seems to want the original data based times not the
! 			// rounded/truncated times in the file name
! 			PDSDate temp1 = firstAgg.getBeginningDateTime();
! 			PDSDate d1 = new PDSDate(temp1.getOriginalPacketTime());
! 
! 			// PDSDate temp2 = firstAgg.getEndingDateTime();
! 			// PDSDate d2 = new PDSDate(temp2.getOriginalPacketTime());
! 
! 			// PDSDate d1 = firstAgg.getBeginningDateTime();
! 
! 			// But this one is offset from it and so is not really a LPEATE or
! 			// LeapDate
! 			// it's the same if you get the original time or not in other words.
! 			// That means we have to substract the leap time from it.
! 			PDSDate d2 = firstAgg.getEndingDateTime();
! 
! 			if (rdrs == null)
! 				return;
! 			if (rdrs.size() <= 0)
! 				return;
! 			if ((d1 == null) || (d2 == null))
! 				return;
! 
! 			NPOESSFilename nfn = new NPOESSFilename(rdrs, d1, d2,
! 					creationDateAndTime, SpacecraftId.npp, orbit, Origin.nfts);
! 
! 			String realFilename = nfn.toString();
! 
! 			File nnew = new File(destPath, realFilename);
! 
! 			old.renameTo(nnew);
! 
! 			createUserBlock(nnew);
! 		}
  	}
  
  	// FIXME only supports either RDRs with "SCIENCE" in the name or the DIARY
! 	private Aggregate findFirstScienceWeightedAggregate(List<RDR> rdrs)
! 			throws RtStpsException {
  		List<RDR> sciRDRs = new LinkedList<RDR>();
  		RDR diaryRDR = null;
  		for (RDR rdr : rdrs) {
! 			String rdrNameStr = rdr.getRDRName().getRDRStringName(); // avoid
! 																		// toString
! 																		// w/RDRName
  			if (rdrNameStr.contains("SCIENCE")) {
  				sciRDRs.add(rdr);
  			} else if (rdrNameStr.contains("DIARY")) {
  				diaryRDR = rdr;
  			} else {
! 				throw new RtStpsException(
! 						"No support for non-science/non-diary RDRs ["
! 								+ rdrNameStr + "]");
  			}
  		}
! 
  		if ((sciRDRs.size() <= 0) && (diaryRDR == null)) {
! 			throw new RtStpsException(
! 					"No science/diary RDRs found -- unable to get first/last time for filename");
  		}
! 
  		Aggregate firstAggregate = null;
  		// if there are any science RDRs, use them...
  		if (sciRDRs.size() > 0) {
***************
*** 181,187 ****
  			// otherwise must be a non-null diary then right?
  			firstAggregate = diaryRDR.getAggregate();
  		}
! 		
  		return firstAggregate;
  	}
  
--- 169,175 ----
  			// otherwise must be a non-null diary then right?
  			firstAggregate = diaryRDR.getAggregate();
  		}
! 
  		return firstAggregate;
  	}
  
***************
*** 189,224 ****
  	private Aggregate findFirstAggregate(List<RDR> rdrs) {
  		Aggregate firstAgg = null;
  		long firstMicros = 0L;
! 		
  		for (RDR rdr : rdrs) {
  			Aggregate agg = rdr.getAggregate();
! 			
! 			long micros = agg.getBeginningDateTime().getMicrosSinceEpoch();
! 			
! 			if (firstMicros == 0L) {
! 				firstMicros = micros;
! 				firstAgg = agg;
! 			} else if (micros < firstMicros) {
! 				firstMicros = micros;
! 				firstAgg = agg;
  			}
  		}
  		return firstAgg;
  	}
  
- 
  	private void createUserBlock(File file) throws RtStpsException {
! 		
  		List<RDR> rdrs = rdrFile.getRDRs();
! 		
! 		if (rdrs == null) return;
! 		
! 		if (rdrs.size() <= 0) return;
! 		
! 		UserBlock userBlock = new UserBlock(MissionName.NPP, PlatformShortName.NPP, rdrs);
! 		
  		userBlock.write(file);
! 		
  		userBlock.close();
  	}
  
--- 177,216 ----
  	private Aggregate findFirstAggregate(List<RDR> rdrs) {
  		Aggregate firstAgg = null;
  		long firstMicros = 0L;
! 
  		for (RDR rdr : rdrs) {
  			Aggregate agg = rdr.getAggregate();
! 			if (agg != null) {
! 
! 				long micros = agg.getBeginningDateTime().getMicrosSinceEpoch();
! 
! 				if (firstMicros == 0L) {
! 					firstMicros = micros;
! 					firstAgg = agg;
! 				} else if (micros < firstMicros) {
! 					firstMicros = micros;
! 					firstAgg = agg;
! 				}
  			}
  		}
  		return firstAgg;
  	}
  
  	private void createUserBlock(File file) throws RtStpsException {
! 
  		List<RDR> rdrs = rdrFile.getRDRs();
! 
! 		if (rdrs == null)
! 			return;
! 
! 		if (rdrs.size() <= 0)
! 			return;
! 
! 		UserBlock userBlock = new UserBlock(MissionName.NPP,
! 				PlatformShortName.NPP, rdrs);
! 
  		userBlock.write(file);
! 
  		userBlock.close();
  	}
  
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDR.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDR.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDR.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/RDR.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 186,192 ****
  		
  		Granule granule = Granule.factory(rap, 
  										1L,
! 										new GranuleId(SpacecraftId.npp, rap.getFirstTime(), 0 /** HACK **/, rap.getTimeSpan()),
  										LEOAFlag.Off,
  										DocumentName ,
  										rap.getPacketTypes(),
--- 186,192 ----
  		
  		Granule granule = Granule.factory(rap, 
  										1L,
! 										new GranuleId(SpacecraftId.npp, rap.getFirstTime(),rdrName),
  										LEOAFlag.Off,
  										DocumentName ,
  										rap.getPacketTypes(),
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/SpacecraftDiaryRawApplicationPackets2.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/SpacecraftDiaryRawApplicationPackets2.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/SpacecraftDiaryRawApplicationPackets2.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/SpacecraftDiaryRawApplicationPackets2.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 2,67 ****
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
! */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
  import gov.nasa.gsfc.drl.rtstps.core.ccsds.Packet;
  import ncsa.hdf.hdf5lib.exceptions.HDF5LibraryException;
  
! public class SpacecraftDiaryRawApplicationPackets2 extends RawApplicationPackets {
  
  	private long firstTime = -1l;
  	private boolean fullGranule = false;
  	private Stats stats = null;
  	private long currentTimeOfGranule = 0l;
  
! 	public SpacecraftDiaryRawApplicationPackets2(SpacecraftId satellite, int setNum, PacketPool packetPool) {
! 		super(satellite,  RDRName.NPP_Ephemeris_and_Attitude, setNum, packetPool);
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
  	}
! 	
! 	public SpacecraftDiaryRawApplicationPackets2(Stats stats, SpacecraftId satellite, int setNum, PacketPool packetPool) {
! 		super(satellite,  RDRName.NPP_Ephemeris_and_Attitude, setNum, packetPool);
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
  		this.stats = stats;
  	}
! 	
  	/**
! 	 * Constructor which attempts to read the RawApplicationPacket entry that pre-exists.
! 	 * The contents of the dataspace are read into a memory buffer... assuming it will fit.
! 	 * @param allRDRId  the rdrAll Groups id
! 	 * @param setNum the set number of raw entry
! 	 * @throws NullPointerException 
! 	 * @throws HDF5LibraryException 
! 	 * @throws RtStpsException 
  	 */
! 	public SpacecraftDiaryRawApplicationPackets2(int allRDRId, int setNum) throws RtStpsException {
  		super(allRDRId, setNum);
  	}
! 	
! 	public SpacecraftDiaryRawApplicationPackets2(int readId, int setNum, boolean usedByGranuleOnly) throws RtStpsException {
  		super(readId, setNum, true);
  	}
  
  
! 	@Override
  	public boolean notFull(Packet p) throws RtStpsException {
  		boolean notFull = true;
! 		//System.out.println("S/C APID:"+p.getApplicationId()+":"+p.getTimeStamp(8));
! 		if (p.getApplicationId() == 11) {  // idea is we allow apid=0 and 8 in but only check for fullness on apid=11
  			long timestamp = p.getTimeStamp(8);
! 			if (this.firstTime < 0l) {
! 				this.firstTime = timestamp;
! 			} else {
! 				
! 				if (greaterThanEqualTo(timestamp, firstTime, 20)) {
! 					notFull = false;  // if 20secs have gone by, the granule is full
! 					fullGranule = true;
  				}
  			}
  		}
--- 2,184 ----
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
!  */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
  import gov.nasa.gsfc.drl.rtstps.core.ccsds.Packet;
  import ncsa.hdf.hdf5lib.exceptions.HDF5LibraryException;
  
! public class SpacecraftDiaryRawApplicationPackets2 extends
! 		RawApplicationPackets {
  
  	private long firstTime = -1l;
  	private boolean fullGranule = false;
  	private Stats stats = null;
  	private long currentTimeOfGranule = 0l;
  
! 	public SpacecraftDiaryRawApplicationPackets2(SpacecraftId satellite,
! 			int setNum, PacketPool packetPool) {
! 		super(satellite, RDRName.NPP_Ephemeris_and_Attitude, setNum, packetPool);
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
  	}
! 
! 	public SpacecraftDiaryRawApplicationPackets2(Stats stats,
! 			SpacecraftId satellite, int setNum, PacketPool packetPool) {
! 		super(satellite, RDRName.NPP_Ephemeris_and_Attitude, setNum, packetPool);
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
  		this.stats = stats;
  	}
! 
  	/**
! 	 * Constructor which attempts to read the RawApplicationPacket entry that
! 	 * pre-exists. The contents of the dataspace are read into a memory
! 	 * buffer... assuming it will fit.
! 	 * 
! 	 * @param allRDRId
! 	 *            the rdrAll Groups id
! 	 * @param setNum
! 	 *            the set number of raw entry
! 	 * @throws NullPointerException
! 	 * @throws HDF5LibraryException
! 	 * @throws RtStpsException
  	 */
! 	public SpacecraftDiaryRawApplicationPackets2(int allRDRId, int setNum)
! 			throws RtStpsException {
  		super(allRDRId, setNum);
  	}
! 
! 	public SpacecraftDiaryRawApplicationPackets2(int readId, int setNum,
! 			boolean usedByGranuleOnly) throws RtStpsException {
  		super(readId, setNum, true);
  	}
  
+ 	// @Override
+ 	// public boolean notFull(Packet p) throws RtStpsException {
+ 	// boolean notFull = true;
+ 	// //System.out.println("S/C APID:"+p.getApplicationId()+":"+p.getTimeStamp(8));
+ 	// if (p.getApplicationId() == 11) { // idea is we allow apid=0 and 8 in but
+ 	// only check for fullness on apid=11
+ 	// long timestamp = p.getTimeStamp(8);
+ 	// if (this.firstTime < 0l) {
+ 	// this.firstTime = timestamp;
+ 	// } else {
+ 	//
+ 	// if (greaterThanEqualTo(timestamp, firstTime, 20)) {
+ 	// notFull = false; // if 20secs have gone by, the granule is full
+ 	// fullGranule = true;
+ 	// }
+ 	// }
+ 	// }
+ 	// return notFull;
+ 	// }
  
! 	// static long firstTime = -1;
! 
! 	/**
! 	 * Granules are created from scans. Scans in VIIRS are lots of packets the
! 	 * first 800 w/with a secondaryheader is used here to signal the start of a
! 	 * scan. We collect it and everything after it as one scan until it
! 	 * re-appears. Anything more complex than this can be built on top of this
! 	 * one assumption.
! 	 * 
! 	 * @param p
! 	 *            a Packet to be put into the VIIRS RawApplicationPackets area
! 	 * @return true if it can be put there, or false if it is full and should be
! 	 *         written to disk first
! 	 * @exception wraps
! 	 *                any HDF exceptions in RtStpsException
! 	 */
  	public boolean notFull(Packet p) throws RtStpsException {
+ 
  		boolean notFull = true;
! 		// System.out.println("S/C APID:"+p.getApplicationId()+":"+p.getTimeStamp(8));
! //		if (p.getApplicationId() == 11) 
! 		{ // idea is we allow apid=0 and 8 in
! 											// but only check for fullness on
! 											// apid=11
! 
  			long timestamp = p.getTimeStamp(8);
! 
! 			GranuleId currentGranId = new GranuleId(SpacecraftId.npp,
! 					p.getTimeStamp(8),
! 					RDRName.NPP_Ephemeris_and_Attitude);
! 
! 			LeapDate obsTime = new LeapDate(timestamp);
! 			// System.out.printf("VIIRS: Gran %s seq %d ts %d obs %d \n",
! 			// currentGranId.toString(), p.getSequenceCounter(),
! 			// timestamp, obsTime.getMicrosSinceEpoch());
! 
! 			if (currentGranId.toString().startsWith("NPP-") == false) {
! 
! 				if (this.firstTime < 0l) {
! 					this.firstTime = timestamp;
! 					setFirstTime(timestamp);
! 				} else {
! 					GranuleId startGranId = new GranuleId(SpacecraftId.npp,
! 							getFirstTime(), 
! 							RDRName.NPP_Ephemeris_and_Attitude);
! 					
! 					
! 					LeapDate startObs = new LeapDate(getFirstTime());  //srm
! 				//	long pktObservationTime = new LeapDate(timestamp).getMicrosSinceEpoch();
! 					
! 					
! 				//	long granuleEndTime =	GranuleId.calcGranuleEndTime(startObs.getMicrosSinceEpoch(), RDRName.NPP_Ephemeris_and_Attitude);
! 
! //					if ( granuleEndTime < pktObservationTime )
! //					{
! //						System.out.printf("DIARY: %s Cur %s e %d ec %d\n" , startGranId.toString()
! //								, currentGranId.toString(),granuleEndTime,pktObservationTime );
! //
! //					}
! 					
! 					
! //					if (startGranId.toString().contentEquals(
! //							currentGranId.toString()) == false) {
! //						firstTime = -1;
! //						System.out.println("DIARY: " + startGranId.toString()
! //								+ " Current:" + currentGranId.toString());
! //
! //						notFull = false; // if 20secs have gone by, the granule
! //											// is full
! //						fullGranule = true;
! //
! //					}
! 					
! 					LPEATEDate lpd = new LPEATEDate(getFirstTime());
! 					long ietTimeThis = lpd.getMicrosSinceEpoch();
! 					long stThis = GranuleId.calcGranuleStartTime(ietTimeThis,
! 							RDRName.NPP_Ephemeris_and_Attitude);
! 
! 					lpd = new LPEATEDate(p.getTimeStamp(8));
! 					long ietTimeNext = lpd.getMicrosSinceEpoch();
! 					long stNext = GranuleId.calcGranuleStartTime(ietTimeNext,
! 							RDRName.NPP_Ephemeris_and_Attitude);
! 
! //					System.out.printf(
! //							"DIARY ietthis: %d start: %d Next %d %d\n",
! //							ietTimeThis, stThis, ietTimeNext, stNext);
! 
! 					
! 					if( stThis != stNext )
! 					{
! //						System.out.println("DIARY: " + startGranId.toString()
! //								+ " Current:" + currentGranId.toString());
! 
! 						notFull = false; // if 20secs have gone by, the granule
! 											// is full
! 						fullGranule = true;
! 
! 					}
! 					
! 					
! 					
! 					
  				}
  			}
  		}
***************
*** 71,167 ****
  	@Override
  	public void put(Packet p) throws RtStpsException {
  		this.updateAppIdCounters(p.getApplicationId());
- 		
- 		if (p.getApplicationId() == 11) {// idea is we allow apid=0 and 8 in but only check for fullness on apid=11
  
! 			// secondary time stamp only valid in in first or standalone packets...
  			if (getFirstTime() == 0L) {
! 				//System.out.println("Here...");
  				setFirstTime(p.getTimeStamp(8));
  			}
! 			
  			setLastTime(p.getTimeStamp(8));
  		}
! 		
  		// the packet is deep copied, it is allocated off a pool
! 		// which may hold previously copied packets...  they must be put
  		// back on the pool when done...
! 		
  		Packet pcopy = CopyPacket.deep(p, packetPool);
! 		
  		getPacketList().add(pcopy);
  	}
! 	
  	/**
! 	 * Write the collected group of packets to the designated HDF file using the handle
  	 * @return true if the RawApplicationPacket was written, false if not
! 	 * @exception any HDF exceptions are wrapped in an RtStpsException
  	 */
  	public boolean write(int hdfFile) throws RtStpsException {
  		boolean ret = true;
  		if (fullGranule == true) {
! 			
! 			
  			if (stats == null) {
! 				System.out.println("Creating Spacecraft Diary Granule -- [" + 20 + "] seconds"); // FIXME do we show them the real time or the near time?
  			} else {
  				stats.ae_createdGranules.value++;
  			}
! 			
  			ret = super.write(hdfFile);
! 			
! 			
  		} else {
! 			
  			if (stats == null) {
! 				double time = currentTimeOfGranule/1000000.0;
! 				System.out.println("Creating Partial Spacecraft Diary Granule -- [" + time + "] seconds");
  			} else {
  				stats.ae_createdGranules.value++;
  			}
! 			
  			ret = super.write(hdfFile);
  		}
! 		
  		fullGranule = false;
  		this.firstTime = -1l;
! 		
  		return ret;
  	}
! 	
  	/**
! 	 * Close out the RawApplicationPacket which writes the results to the HDF file and cleans up.
! 	 * @exception any HDF exceptions are wrapped in an RtStpsException
  	 */
  	public void close() throws RtStpsException {
  		super.close();
! 		this.firstTime = -1L; 
  		fullGranule = false;
  	}
! 	
  	// see if time between current time and old time is X seconds or more
! 	public boolean greaterThanEqualTo(long timeStamp1, long timeStamp2, int seconds) {
! 		
  		long rawDay1 = (timeStamp1 >> 48) & 0x0ffffL;
  		long rawMillis1 = (timeStamp1 >> 16) & 0x0ffffffffL;
  		long rawMicros1 = timeStamp1 & 0x0ffffL;
! 		
  		long micros1 = 86400000000l * rawDay1;
  		micros1 += rawMillis1 * 1000l;
  		micros1 += rawMicros1;
! 		
  		long rawDay2 = (timeStamp2 >> 48) & 0x0ffffL;
  		long rawMillis2 = (timeStamp2 >> 16) & 0x0ffffffffL;
  		long rawMicros2 = timeStamp2 & 0x0ffffL;
! 		
  		long micros2 = 86400000000l * rawDay2;
  		micros2 += rawMillis2 * 1000l;
  		micros2 += rawMicros2;
! 		
  		currentTimeOfGranule = micros1 - micros2;
! 		
! 		long tmp2 = (long)seconds * 1000000l;
  		return (currentTimeOfGranule >= tmp2);
  	}
! 	
  }
--- 188,296 ----
  	@Override
  	public void put(Packet p) throws RtStpsException {
  		this.updateAppIdCounters(p.getApplicationId());
  
! 		if (p.getApplicationId() == 11) {// idea is we allow apid=0 and 8 in but
! 											// only check for fullness on
! 											// apid=11
! 
! 			// secondary time stamp only valid in in first or standalone
! 			// packets...
  			if (getFirstTime() == 0L) {
! 				// System.out.println("Here...");
  				setFirstTime(p.getTimeStamp(8));
  			}
! 
  			setLastTime(p.getTimeStamp(8));
  		}
! 
  		// the packet is deep copied, it is allocated off a pool
! 		// which may hold previously copied packets... they must be put
  		// back on the pool when done...
! 
  		Packet pcopy = CopyPacket.deep(p, packetPool);
! 
  		getPacketList().add(pcopy);
  	}
! 
  	/**
! 	 * Write the collected group of packets to the designated HDF file using the
! 	 * handle
! 	 * 
  	 * @return true if the RawApplicationPacket was written, false if not
! 	 * @exception any
! 	 *                HDF exceptions are wrapped in an RtStpsException
  	 */
  	public boolean write(int hdfFile) throws RtStpsException {
  		boolean ret = true;
  		if (fullGranule == true) {
! 
  			if (stats == null) {
! 				System.out.println("Creating Spacecraft Diary Granule -- ["
! 						+ 20 + "] seconds"); // FIXME do we show them the real
! 												// time or the near time?
  			} else {
  				stats.ae_createdGranules.value++;
  			}
! 
  			ret = super.write(hdfFile);
! 
  		} else {
! 
  			if (stats == null) {
! 				double time = currentTimeOfGranule / 1000000.0;
! 				System.out
! 						.println("Creating Partial Spacecraft Diary Granule -- ["
! 								+ time + "] seconds");
  			} else {
  				stats.ae_createdGranules.value++;
  			}
! 
  			ret = super.write(hdfFile);
  		}
! 
  		fullGranule = false;
  		this.firstTime = -1l;
! 
  		return ret;
  	}
! 
  	/**
! 	 * Close out the RawApplicationPacket which writes the results to the HDF
! 	 * file and cleans up.
! 	 * 
! 	 * @exception any
! 	 *                HDF exceptions are wrapped in an RtStpsException
  	 */
  	public void close() throws RtStpsException {
  		super.close();
! 		this.firstTime = -1L;
  		fullGranule = false;
  	}
! 
  	// see if time between current time and old time is X seconds or more
! 	public boolean greaterThanEqualTo(long timeStamp1, long timeStamp2,
! 			int seconds) {
! 
  		long rawDay1 = (timeStamp1 >> 48) & 0x0ffffL;
  		long rawMillis1 = (timeStamp1 >> 16) & 0x0ffffffffL;
  		long rawMicros1 = timeStamp1 & 0x0ffffL;
! 
  		long micros1 = 86400000000l * rawDay1;
  		micros1 += rawMillis1 * 1000l;
  		micros1 += rawMicros1;
! 
  		long rawDay2 = (timeStamp2 >> 48) & 0x0ffffL;
  		long rawMillis2 = (timeStamp2 >> 16) & 0x0ffffffffL;
  		long rawMicros2 = timeStamp2 & 0x0ffffL;
! 
  		long micros2 = 86400000000l * rawDay2;
  		micros2 += rawMillis2 * 1000l;
  		micros2 += rawMicros2;
! 
  		currentTimeOfGranule = micros1 - micros2;
! 
! 		long tmp2 = (long) seconds * 1000000l;
  		return (currentTimeOfGranule >= tmp2);
  	}
! 
  }
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/SpacecraftDiaryRDR.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/SpacecraftDiaryRDR.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/SpacecraftDiaryRDR.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/SpacecraftDiaryRDR.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 249,255 ****
  
  		Granule granule = Granule.factory(rap,
  										1L,
! 										new GranuleId(SpacecraftId.npp, rap.getFirstTime(), 0 /** HACK **/, rap.getTimeSpan()),
  										LEOAFlag.Off,
  										RDR.DocumentName,
  										rap.getPacketTypes(),
--- 249,255 ----
  
  		Granule granule = Granule.factory(rap,
  										1L,
! 										new GranuleId(SpacecraftId.npp, rap.getFirstTime(),rdrName),
  										LEOAFlag.Off,
  										RDR.DocumentName,
  										rap.getPacketTypes(),
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/StaticHeader.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/StaticHeader.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/StaticHeader.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/StaticHeader.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 2,8 ****
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
! */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
--- 2,8 ----
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
!  */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
***************
*** 17,649 ****
  import ncsa.hdf.hdf5lib.exceptions.HDF5LibraryException;
  
  /**
!  * Implements the StaticHeader for the RawApplication area, this class can be used to either create the
!  * StaticHeader or read a pre-existing StaticHeader.
   * 
   * 
-  *
   */
  public class StaticHeader {
! 	// note: at the moment the Uint32s are being treated as signed ints, this halves the value
! 	// but it does not seem very likely this code will ever create anything even approaching those
! 	// sizes anyway... this could be a problem though, in which case they should all be longs and masked
  	// when storing...
- 	
- 		private final static int HeaderSize = 72;  // fixed
- 		// static header portion of the static header
- 		// satellite char[4] array in header, addr 0
- 		// sensor char[16], addr 4
- 		// typeid char[16], addr 20
- 		private int numAppIds = 0; // Uint32, address 36
- 		private int apidListOffset = HeaderSize; // Uint32, 72 is the fixed value at this time, address 40
- 		private int pktTrackerOffset = 0; // Uint32, address 44
- 		private int apStorageOffset = 0; // Uint32, address 48
- 		private int nextPktPos = 0;  // Uint32, address 52
- 		private long startBoundary = 0L;  // int64, address 56
- 		private long endBoundary = 0L;  // int64, address 64
- 		// address end is 72
- 		
- 		// most of these are used in BUILDING the static header
- 		// but not used if the dataset has been read in and passed in
- 		// as a byte array... MAYBE 
- 		//
- 		private RDRAppIdList rdrList;
- 		private PacketTrackerList packetTracker;
- 		private ApStorageArea apStorageArea;
- 		
- 		private int dataSet;
- 		//private int packetSizeSum = 0;
- 		private SpacecraftId satellite;
- 		
- 		private RDRName rdrName;
- 		
- 		private List<Packet> packetList;
- 		
- 		private byte[] data;
- 		private int offset = 0;
- 		
- 		
- 		private Sensor sensor;
- 		private int bufSize = 0;
- 		
- 		/**
- 		 * Create a static header from an input packet list, used to write to the HDF
- 		 * @param satellite the name of the satellite
- 		 * @param rdrName the RDR name
- 		 * @param packetList the list of packets that the static header needs to track that go into a particular RawApplicationPackets area
- 		 */
- 		public StaticHeader(SpacecraftId satellite, RDRName rdrName, List<Packet> packetList) {
- 			
- 			//this.dataSet = dataSet;
- 			this.satellite = satellite;
- 			this.rdrName = rdrName;	
- 			this.packetList = packetList;
- 			
- 	
- 			numAppIds = rdrName.getNumberOfAppIdsInRDR();
- 			
- 			// calculate the Ap Storage Area first (note: no longer of importance)
- 			apStorageArea = new ApStorageArea(packetList);
- 			
- 			packetTracker = new PacketTrackerList(rdrName, packetList);
- 			
- 			// then build the RDR list, it depends on the packetTracker list...
- 			rdrList = new RDRAppIdList(rdrName, packetList, packetTracker);
- 			
- 			pktTrackerOffset = HeaderSize + rdrList.getSize();
- 			
- 			apStorageOffset = HeaderSize + rdrList.getSize() + packetTracker.getSize();
- 			
- 			nextPktPos = this.getSize();
- 			
  
! 			
! 		}
  
! 		/**
! 		 * Create a SequentialPacketReader which allows the packets in a particular RawApplicationPackets area
! 		 * to be read out sequentially using the information in the StaticHeader.
! 		 * @return a SequentialPacketReader
! 		 */
! 		public SequentialPacketReader createSequentialPacketReader() {
! 			
! 			return new SequentialPacketReader(new CopyPacketFactory(), this);
! 			
! 		}
! 		
! 		/**
! 		 * Create a RandomAccessPacketReader which allows the packet in a particular RawApplicationPackets area
! 		 * to be read out by random access using the information in the StaticHeader.
! 		 * @return a RandomAccessPacketReader
! 		 */
! 		public RandomAccessPacketReader createRandomAccessPacketReader() {
! 			return new RandomAccessPacketReader(new RandomAccessPacketFactory(), this);
! 		}
! 		
! 		/**
! 		 * Used to parse out of a static header read in as part of reading a pre-existing HDF file.
! 		 * Note that the input data buffer has been read by some other entity and passed to this routine
! 		 * which cracks it apart.
! 		 * @param data containing the static header
! 		 */
! 		public StaticHeader(byte[] data) {
! 			this.data = data; // save a pointer to the original input, not sure this is truly a good idea
! 			//satellite = SpacecraftId.valueOf(readSatelliteString(0, data));
! 			
! 			//sensor = Sensor.valueOf(readSensorString(5, data));
! 			
! 			
! 			numAppIds = (((int)data[36] << 24) & 0xff000000) | // 36, 32 bits
! 						(((int)data[37] << 16) & 0x00ff0000) | 
! 						(((int)data[38] <<  8) & 0x0000ff00) | 
! 						 ((int)data[39] & 0x000000ff);
! 			
! 			pktTrackerOffset = (((int)data[44] << 24) & 0xff000000) | // 44, 32 bits
! 			  					(((int)data[45] << 16) & 0x00ff0000) | 
! 			  					(((int)data[46] <<  8) & 0x0000ff00) | 
! 			  					((int)data[47] & 0x000000ff);
! 			
! 			apStorageOffset = (((int)data[48] << 24) & 0xff000000) | // 48, 32 bits
! 							  (((int)data[49] << 16) & 0x00ff0000) | 
! 							  (((int)data[50] <<  8) & 0x0000ff00) | 
! 							   ((int)data[51] & 0x000000ff);
! 			
! 			nextPktPos = (((int)data[52] << 24) & 0xff000000) | // 52, 32 bits
! 			  			 (((int)data[53] << 16) & 0x00ff0000) | 
! 			  			 (((int)data[54] <<  8) & 0x0000ff00) | 
! 			  			 ((int)data[55] & 0x000000ff);
! 			
! 			
! 			//System.out.println("Number of APID list items [" + ((this.pktTrackerOffset - this.apidListOffset)/32) + "]");
! 			// as it stand now the nextPktPos should equal the data.length -- TESTING
! 			if (nextPktPos != data.length) {
! 				System.out.println(">> Warning: there is a nextPktPos[" + nextPktPos + "] data.length [" + data.length + "] discrepency!!!");
! 			}
! 		}
! 		
! 	
  
! 		/**
! 		 * Return a pointer to the original input data used for reading out the contents of the StaticHeader read
! 		 * out of the RawApplicationPackets area.
! 		 * @return a byte array of the data
! 		 */
! 		public byte[] getData() {
! 			return this.data;
! 		}
! 		
! 		/**
! 		 * Return the ApStorageOffset value
! 		 * @return the offset
! 		 */
! 		public int getApStorageOffset() {
! 			return apStorageOffset;
! 		}
! 		
! 		/**
! 		 * Return the total size of the StaticHeader which is the fixed sized of the StaticHeader area plus the RDR list size
! 		 * and the packet tracker size.
! 		 * @return the sum of the sizes
! 		 */
! 		public int getTotalHeaderSize() {
! 			return HeaderSize + rdrList.getSize() + packetTracker.getSize();
! 		}
  
- 		/**
- 		 * Return the packet store size
- 		 * @return the size
- 		 */
- 		public int getPacketStoreSize() {
- 			return this.apStorageArea.getSize();
- 		}
- 		
- 		/**
- 		 * Return the size of the StaticHeader, the RDR list size, the packet tacker size and the packet store size itself
- 		 * @return the sum of all the sizes
- 		 */
- 		public int getSize() {
- 			return getTotalHeaderSize() + getPacketStoreSize();
- 		}
  
! 		/**
! 		 * Return the AppIdList offset in the StaticHeader area
! 		 * @return the offset
! 		 */
! 		public int getAppIdListOffset() {
! 			return this.apidListOffset;
! 		}
! 		
! 		/**
! 		 * Return the packet tracker offset in the StaticHeader area
! 		 * @return the offset
! 		 */
! 		public int getPktTrackerOffset() {
! 			return this.pktTrackerOffset;
! 		}
! 		
! 		public int getNextPktPos() {
! 			return this.nextPktPos;
! 		}
! 		/**
! 		 * Write from the various sources of input the StaticHeader and the packet storage area to the RawApplicationPackets
! 		 * based on the HDF DataSet handle.
! 		 * @param dataSet the HDF handle to the RawApplicationPackets
! 		 * @throws RtStpsException wrapped HDF or other exceptions
! 		 */
! 		public void write(int dataSet) throws RtStpsException {
! 			// write static header fields
! 			this.dataSet = dataSet; // FIXME maybe, this could be passed into the constructor...
! 			
! 			//System.out.println("static header size: " + this.getSize());
! 			int neededSize = this.getSize();
! 			neededSize = ((neededSize / 1024) * 1024) + 1024;
! 			
! 			//System.out.println("static header size: " + this.getSize() + " Rounded up: " + neededSize + " bufsize: " + bufSize);
! 			if (neededSize > bufSize ) { 
! 				this.data = new byte[neededSize /* this.getSize() */ ]; // must be dynamically calculated depending on inputs
! 				bufSize = neededSize;
! 			}
! 		
! 			writeSatellite();
! 		
! 			writeSensor();
! 		
! 			writeTypeID();
! 		
! 			writeNumAppIds();
! 		
! 			writeApidListOffset();
! 		
! 			writePktTrackerOffset();
! 		
! 			writeApStorageOffset();
! 		
! 			writeNextPktPos();
! 		
! 			writeStartBoundary();  //FIXME must be called first
! 		
! 			writeEndBoundary();
! 		
! 			offset = rdrList.write(data, offset);
! 		
! 			offset = packetTracker.write(data, offset);
! 		
! 			// writeApplicationStorageArea();
! 		
! 			offset = apStorageArea.write(data, offset);
! 		
! 			writeToHDF();
! 			
! 			//this.data = null;
! 			
  		}
  
! 		public String readSatelliteString() {
! 			String satellite = new String(data, 0, 4, Charset.forName("US-ASCII") ).trim();
! 			return satellite;
! 		}
! 		
! 		/**
! 		 * Write the satellite name to the StaticHeader data buffer, converting it to ASCII first
! 		 */
! 		private void writeSatellite() {
! 			
! 			//System.out.println("Satellite = " + satellite);
! 			
! 			byte[] ascii = satellite.toString().getBytes(Charset.forName("US-ASCII"));
! 			
! 			
! 			//System.out.println("ascii length = " + ascii.length);
! 			
! 			//System.out.println("data length = " + data.length);
! 			data[offset++] = ascii[0];
! 			data[offset++] = ascii[1];
! 			data[offset++] = ascii[2];
! 			data[offset++] = 0;
  
! 		}
  
! 		public String readSensorString() {
! 			String sensor = new String(data, 4, 16, Charset.forName("US-ASCII")) .trim();
! 			return sensor;
! 		}
! 		
! 		/**
! 		 * Write the sensor name to the StaticHeader data buffer, converting it to ASCII first
! 		 */
! 		private void writeSensor() {
! 			//System.out.println("rdrName.getSensor: " + rdrName.getSensor().toString());
! 			
! 			byte[] ascii = rdrName.getSensor().toString().getBytes(Charset.forName("US-ASCII"));
! 			
! 			//System.out.println("Sensor length: " + ascii.length);
! 			
! 			for (int i = 0; i < 16; i++) {
! 				data[offset+i] = 0;
! 			}
! 			int copyLen = ascii.length;
! 			if (copyLen > 16) copyLen = 16;
! 			
! 			for (int i = 0; i < copyLen; i++) {
! 				data[offset + i] = ascii[i];
! 			}
! 			offset += 16;
! 		}
  
! 		public String readTypeIDString() {
! 			String typeID = new String(data, 20, 16, Charset.forName("US-ASCII")) .trim();
! 			return typeID;
! 		}
  		
- 		/**
- 		 * Write the type id name to the StaticHeader data buffer, converting it to ASCII first
- 		 */
- 		private void writeTypeID() {
- 			
- 			//System.out.println("rdrName.getTypeID: " + rdrName.getTypeID().toString());
- 			
- 			byte[] ascii = rdrName.getTypeID().toString().getBytes(Charset.forName("US-ASCII"));
- 			
- 			
- 			//System.out.println("TypeId length: " + ascii.length);
- 			
- 			for (int i = 0; i < 16; i++) {
- 				data[offset+i] = 0;
- 			}
- 			int copyLen = ascii.length;
- 			if (copyLen > 16) copyLen = 16;
- 			
- 			for (int i = 0; i < copyLen; i++) {
- 				data[offset + i] = ascii[i];
- 			}
- 			offset += 16;
- 		}
- 		
- 		public int readNumAppIds() {
- 			int numAppIds = ( (int)data[36] << 24 ) | 
- 								(((int)data[37] << 16) & 0x00ff0000) | 
- 								(((int)data[38] <<  8) & 0x0000ff00) | 
- 								((int)data[39] & 0x000000ff) ;
- 			return numAppIds;
- 		}
- 		/**
- 		 * Write the number of application IDs to the StaticHeader data buffer
- 		 */
- 		private void writeNumAppIds() {
- 			//numAppIds = rdrName.getNumberOfAppIdsInRDR();
- 			data[offset++] = (byte)((numAppIds >>> 24) & 0x0ff);
- 			data[offset++] = (byte)((numAppIds >>> 16) & 0x0ff);
- 			data[offset++] = (byte)((numAppIds >>> 8) & 0x0ff);
- 			data[offset++] = (byte)(numAppIds & 0x0ff);
- 		
- 		}
- 		
- 		
- 		public long readApidListOffset() {
- 			int apidListOffset = ( (int)data[40] << 24 ) | 
- 							(((int)data[41] << 16) & 0x00ff0000) | 
- 							(((int)data[42] <<  8) & 0x0000ff00) | 
- 							((int)data[43] & 0x000000ff) ;
- 			return apidListOffset;
- 		}
- 		/**
- 		 * Write the application ID list offset to the StaticHeader data buffer
- 		 */
- 		private void writeApidListOffset() {
- 			
- 			data[offset++] = (byte)((apidListOffset >>> 24) & 0x0ff);
- 			data[offset++] = (byte)((apidListOffset >>> 16) & 0x0ff);
- 			data[offset++] = (byte)((apidListOffset >>> 8) & 0x0ff);
- 			data[offset++] = (byte)(apidListOffset & 0x0ff);
- 			
- 		}
- 		
- 		public RDRAppIdList readRDRAppIdList() {
- 			
- 			return new RDRAppIdList((int)readApidListOffset(), data, (int)readPktTrackerOffset());
- 		}
- 
- 		public long readPktTrackerOffset() {
- 			int pktTrackerOffset = ( (int)data[44] << 24 ) | 
- 									(((int)data[45] << 16) & 0x00ff0000) | 
- 									(((int)data[46] <<  8) & 0x0000ff00) | 
- 									((int)data[47] & 0x000000ff) ;
- 			return pktTrackerOffset;
- 		}
- 		
- 		/**
- 		 * Write the packet tracker offset to the StaticHeader data buffer
- 		 */
- 		private void writePktTrackerOffset() {
- 			
- 			data[offset++] = (byte)((pktTrackerOffset >>> 24) & 0x0ff);
- 			data[offset++] = (byte)((pktTrackerOffset >>> 16) & 0x0ff);
- 			data[offset++] = (byte)((pktTrackerOffset >>> 8) & 0x0ff);
- 			data[offset++] = (byte)(pktTrackerOffset & 0x0ff);
- 			
- 		}
- 
- 		public long readApStorageOffset() {
- 			int apStorageOffset = ( (int)data[48] << 24 ) | 
- 									(((int)data[49] << 16) & 0x00ff0000) | 
- 									(((int)data[50] <<  8) & 0x0000ff00) | 
- 									((int)data[51] & 0x000000ff) ;
- 			return apStorageOffset;
- 		}
- 		
- 		/**
- 		 * Write the ap storage offset to the StaticHeader data buffer
- 		 */
- 		private void writeApStorageOffset() {
- 			//System.out.println("Creating storage offset at offset: " + offset + " value of it: " + apStorageOffset);
- 			data[offset++] = (byte)((apStorageOffset >>> 24) & 0x0ff);
- 			data[offset++] = (byte)((apStorageOffset >>> 16) & 0x0ff);
- 			data[offset++] = (byte)((apStorageOffset >>> 8) & 0x0ff);
- 			data[offset++] = (byte)(apStorageOffset & 0x0ff);
  	
- 			//System.out.println("offset now = " + offset);
- 			
- 		}
- 
- 		public long readNextPktPos() {
- 			int nextPktPos = ( (int)data[52] << 24 ) | 
- 									(((int)data[53] << 16) & 0x00ff0000) | 
- 										(((int)data[54] <<  8) & 0x0000ff00) | 
- 										((int)data[55] & 0x000000ff) ;
- 			return nextPktPos;
- 		}
- 		
- 		/**
- 		 * Write the next packet position to the StaticHeader data buffer
- 		 */
- 		private void writeNextPktPos() {
- 			data[offset++] = (byte)((nextPktPos >>> 24) & 0x0ff);
- 			data[offset++] = (byte)((nextPktPos >>> 16) & 0x0ff);
- 			data[offset++] = (byte)((nextPktPos >>> 8) & 0x0ff);
- 			data[offset++] = (byte)(nextPktPos & 0x0ff);
- 
- 		}
- 
- 		public long readStartBoundary() {
- 			long startBoundary = 0L;
- 			int loffset = 56;
- 			startBoundary =  ((long)data[loffset++] << 56) & 0xff00000000000000l;
- 			startBoundary |= ((long)data[loffset++] << 48) & 0x00ff000000000000l;
- 			startBoundary |= ((long)data[loffset++] << 40) & 0x0000ff0000000000l;
- 			startBoundary |= ((long)data[loffset++] << 32) & 0x000000ff00000000l;
- 			startBoundary |= ((long)data[loffset++] << 24) & 0x00000000ff000000l;
- 			startBoundary |= ((long)data[loffset++] << 16) & 0x0000000000ff0000l;
- 			startBoundary |= ((long)data[loffset++] <<  8) & 0x000000000000ff00l;
- 			startBoundary |=  (long)data[loffset++]        & 0x00000000000000ffl;
- 			
- 			return startBoundary;
- 		}
- 		
- 		/**
- 		 * Write the start boundary to the StaticHeader data buffer
- 		 */
- 		private void writeStartBoundary() {
- 			Packet firstPacket = getFirstPacketWithTimestamp();  
- 			// we don't check for non-null result... assume that's fatal issue right now that needs to be checked
- 			
- 			//System.out.println("First packet end boundary: " + PDSDate.getMicrosSinceEpoch(firstPacket.getTimeStamp(8)));
- 			
- 			//startBoundary = PDSDate.getMicrosSinceEpoch(firstPacket.getTimeStamp(8));
- 			long ietTime = 0L;
- 			if ((rdrName == RDRName.VIIRS_Science) ||  (rdrName == RDRName.NPP_Ephemeris_and_Attitude)) {
- 				
- 				LPEATEDate lpd = new LPEATEDate(firstPacket.getTimeStamp(8));
- 				ietTime = lpd.getMicrosSinceEpoch();
- 				
- 			} else {
- 				ietTime = PDSDate.getMicrosSinceEpoch(firstPacket.getTimeStamp(8));
- 			}
- 			
- 			startBoundary = ietTime;
- 			
- 			// VIIRS partial test
- 			//if (rdrName == RDRName.VIIRS_Science) {
- 			//	startBoundary = 1422168873750000L; // was just ietTime
- 			//}
- 			
- 			data[offset++] = (byte)((startBoundary >>> 56) & 0x0ffL);
- 			data[offset++] = (byte)((startBoundary >>> 48) & 0x0ffL);
- 			data[offset++] = (byte)((startBoundary >>> 40) & 0x0ffL);
- 			data[offset++] = (byte)((startBoundary >>> 32) & 0x0ffL);
- 			data[offset++] = (byte)((startBoundary >>> 24) & 0x0ffL);
- 			data[offset++] = (byte)((startBoundary >>> 16) & 0x0ffL);
- 			data[offset++] = (byte)((startBoundary >>> 8) & 0x0ffL);
- 			data[offset++] = (byte)(startBoundary & 0x0ffL);
  
- 
- 		}
- 		
- 		// there an assumption there will be one, otherwise this ultimately will result in a 
- 		// null pointer exception where used...
- 		
- 		private Packet getFirstPacketWithTimestamp() {
- 			for (Packet p : packetList) {
- 				if (p.hasSecondaryHeader()) {
- 					return p;
- 				}
- 			}
- 			return null;
- 		}
- 
- 		public long readEndBoundary() {
- 			long endBoundary = 0L;
- 			int loffset = 64;
- 			endBoundary =  ((long)data[loffset++] << 56) & 0xff00000000000000l;
- 			endBoundary |= ((long)data[loffset++] << 48) & 0x00ff000000000000l;
- 			endBoundary |= ((long)data[loffset++] << 40) & 0x0000ff0000000000l;
- 			endBoundary |= ((long)data[loffset++] << 32) & 0x000000ff00000000l;
- 			endBoundary |= ((long)data[loffset++] << 24) & 0x00000000ff000000l;
- 			endBoundary |= ((long)data[loffset++] << 16) & 0x0000000000ff0000l;
- 			endBoundary |= ((long)data[loffset++] <<  8) & 0x000000000000ff00l;
- 			endBoundary |=  (long)data[loffset++]        & 0x00000000000000ffl;
- 			
- 			return endBoundary;
- 		}
- 
- 		/**
- 		 * Write the end boundary to the StaticHeader data buffer
- 		 */
- 		private void writeEndBoundary() {
- 			
- 			Packet lastPacket = getLastPacketWithTimestamp();
- 			// we don't check for non-null result... assume that's fatal issue right now that needs to be checked
- 			//System.out.println("Last packet end boundary: " + PDSDate.getMicrosSinceEpoch(lastPacket.getTimeStamp(8)));
- 			long ietTime = 0L;
- 			
- 			if ((rdrName == RDRName.VIIRS_Science) || (rdrName == RDRName.NPP_Ephemeris_and_Attitude)) {
- 				
- 				LPEATEDate lpd = new LPEATEDate(lastPacket.getTimeStamp(8));
- 				ietTime = lpd.getMicrosSinceEpoch();
- 				
- 				
- 				if (rdrName == RDRName.VIIRS_Science) {
- 					ietTime += 1400000L; // 1350000L worked for the 1st set, this works for the 2nd
- 				} else if (rdrName == RDRName.NPP_Ephemeris_and_Attitude) {
- 					ietTime += 1000000L;
- 				}
- 
- 			} else {
- 				ietTime = PDSDate.getMicrosSinceEpoch(lastPacket.getTimeStamp(8)) + 1L; // non-inclusive
- 			}
- 			
- 			endBoundary = ietTime;
- 			
- 			// VIIRS partial test
- 			//if (rdrName == RDRName.VIIRS_Science) {
- 			//	endBoundary = 1422168959100000L;
- 			//}
- 			
- 			data[offset++] = (byte)((endBoundary >>> 56) & 0x0ffL);
- 			data[offset++] = (byte)((endBoundary >>> 48) & 0x0ffL);
- 			data[offset++] = (byte)((endBoundary >>> 40) & 0x0ffL);
- 			data[offset++] = (byte)((endBoundary >>> 32) & 0x0ffL);
- 			data[offset++] = (byte)((endBoundary >>> 24) & 0x0ffL);
- 			data[offset++] = (byte)((endBoundary >>> 16) & 0x0ffL);
- 			data[offset++] = (byte)((endBoundary >>> 8) & 0x0ffL);
- 			data[offset++] = (byte)(endBoundary & 0x0ffL);
- 			
  	
! 		}
! 
! 		/**
! 		private void writeApplicationStorageArea() throws HDF5LibraryException, NullPointerException {
! 			System.out.println("Counter basedd Offset into storage area: " + offset);
! 			for (Packet p : packetList) {
! 				System.out.println("p.getSize()" + p.getSize());
! 				writeBytes(p.getData(), p.getSize());
! 			}
! 			
! 		}
! 
! 		private void writeBytes(byte[] from, int size) {
! 			for (int i = 0; i < size; i++) {
! 				this.data[offset++] = from[i];
! 			}
! 		}
! 		 * @throws RtStpsException 
! 		**/
  		
  		
- 		// there an assumption there will be one, otherwise this ultimately will result in a 
- 		// null pointer exception where used...
- 		
- 		private Packet getLastPacketWithTimestamp() {
- 			int end = packetList.size() - 1;
- 			
- 			// for larger granules this could be worth it
- 			for (int i = end; i >= 0; i--) {
- 				
- 				Packet p = packetList.get(i);
- 				if (p.hasSecondaryHeader()) {
- 					return p;
- 				}
- 			}
- 			return null;
- 		}
- 
- 		/**
- 		 * Write the entire filled out data buffer to the HDF file 
- 		 * at the specified DataSet handle using the data buffer array
- 		 * @exception wraps any HDF exceptions in an RtStpsException
- 		 */
- 		private void writeToHDF() throws RtStpsException {
- 			try {
- 				H5.H5Dwrite(dataSet,
- 					     HDF5Constants.H5T_STD_U8BE,
- 					     HDF5Constants.H5S_ALL, 
- 					     HDF5Constants.H5S_ALL, 
- 						 HDF5Constants.H5P_DEFAULT,
- 						 data);
- 			} catch (HDF5LibraryException e) {
- 				throw new RtStpsException(e);
- 			}
- 		}
  
  
  
  }
--- 17,706 ----
  import ncsa.hdf.hdf5lib.exceptions.HDF5LibraryException;
  
  /**
!  * Implements the StaticHeader for the RawApplication area, this class can be
!  * used to either create the StaticHeader or read a pre-existing StaticHeader.
!  * 
   * 
   * 
   */
  public class StaticHeader {
! 	// note: at the moment the Uint32s are being treated as signed ints, this
! 	// halves the value
! 	// but it does not seem very likely this code will ever create anything even
! 	// approaching those
! 	// sizes anyway... this could be a problem though, in which case they should
! 	// all be longs and masked
  	// when storing...
  
! 	private final static int HeaderSize = 72; // fixed
! 	// static header portion of the static header
! 	// satellite char[4] array in header, addr 0
! 	// sensor char[16], addr 4
! 	// typeid char[16], addr 20
! 	private int numAppIds = 0; // Uint32, address 36
! 	private int apidListOffset = HeaderSize; // Uint32, 72 is the fixed value at
! 												// this time, address 40
! 	private int pktTrackerOffset = 0; // Uint32, address 44
! 	private int apStorageOffset = 0; // Uint32, address 48
! 	private int nextPktPos = 0; // Uint32, address 52
! 	private long startBoundary = 0L; // int64, address 56
! 	private long endBoundary = 0L; // int64, address 64
! 	// address end is 72
! 
! 	// most of these are used in BUILDING the static header
! 	// but not used if the dataset has been read in and passed in
! 	// as a byte array... MAYBE
! 	//
! 	private RDRAppIdList rdrList;
! 	private PacketTrackerList packetTracker;
! 	private ApStorageArea apStorageArea;
! 
! 	private int dataSet;
! 	// private int packetSizeSum = 0;
! 	private SpacecraftId satellite;
! 
! 	private RDRName rdrName;
! 
! 	private List<Packet> packetList;
! 
! 	private byte[] data;
! 	private int offset = 0;
! 
! 	private Sensor sensor;
! 	private int bufSize = 0;
! 
! 	/**
! 	 * Create a static header from an input packet list, used to write to the
! 	 * HDF
! 	 * 
! 	 * @param satellite
! 	 *            the name of the satellite
! 	 * @param rdrName
! 	 *            the RDR name
! 	 * @param packetList
! 	 *            the list of packets that the static header needs to track that
! 	 *            go into a particular RawApplicationPackets area
! 	 */
! 	public StaticHeader(SpacecraftId satellite, RDRName rdrName,
! 			List<Packet> packetList) {
! 
! 		// this.dataSet = dataSet;
! 		this.satellite = satellite;
! 		this.rdrName = rdrName;
! 		this.packetList = packetList;
! 
! 		numAppIds = rdrName.getNumberOfAppIdsInRDR();
! 
! 		// calculate the Ap Storage Area first (note: no longer of importance)
! 		apStorageArea = new ApStorageArea(packetList);
! 
! 		packetTracker = new PacketTrackerList(rdrName, packetList);
! 
! 		// then build the RDR list, it depends on the packetTracker list...
! 		rdrList = new RDRAppIdList(rdrName, packetList, packetTracker);
! 
! 		pktTrackerOffset = HeaderSize + rdrList.getSize();
! 
! 		apStorageOffset = HeaderSize + rdrList.getSize()
! 				+ packetTracker.getSize();
! 
! 		nextPktPos = this.getSize();
! 
! 	}
! 
! 	/**
! 	 * Create a SequentialPacketReader which allows the packets in a particular
! 	 * RawApplicationPackets area to be read out sequentially using the
! 	 * information in the StaticHeader.
! 	 * 
! 	 * @return a SequentialPacketReader
! 	 */
! 	public SequentialPacketReader createSequentialPacketReader() {
! 
! 		return new SequentialPacketReader(new CopyPacketFactory(), this);
! 
! 	}
! 
! 	/**
! 	 * Create a RandomAccessPacketReader which allows the packet in a particular
! 	 * RawApplicationPackets area to be read out by random access using the
! 	 * information in the StaticHeader.
! 	 * 
! 	 * @return a RandomAccessPacketReader
! 	 */
! 	public RandomAccessPacketReader createRandomAccessPacketReader() {
! 		return new RandomAccessPacketReader(new RandomAccessPacketFactory(),
! 				this);
! 	}
! 
! 	/**
! 	 * Used to parse out of a static header read in as part of reading a
! 	 * pre-existing HDF file. Note that the input data buffer has been read by
! 	 * some other entity and passed to this routine which cracks it apart.
! 	 * 
! 	 * @param data
! 	 *            containing the static header
! 	 */
! 	public StaticHeader(byte[] data) {
! 		this.data = data; // save a pointer to the original input, not sure this
! 							// is truly a good idea
! 		// satellite = SpacecraftId.valueOf(readSatelliteString(0, data));
! 
! 		// sensor = Sensor.valueOf(readSensorString(5, data));
! 
! 		numAppIds = (((int) data[36] << 24) & 0xff000000)
! 				| // 36, 32 bits
! 				(((int) data[37] << 16) & 0x00ff0000)
! 				| (((int) data[38] << 8) & 0x0000ff00)
! 				| ((int) data[39] & 0x000000ff);
! 
! 		pktTrackerOffset = (((int) data[44] << 24) & 0xff000000)
! 				| // 44, 32 bits
! 				(((int) data[45] << 16) & 0x00ff0000)
! 				| (((int) data[46] << 8) & 0x0000ff00)
! 				| ((int) data[47] & 0x000000ff);
! 
! 		apStorageOffset = (((int) data[48] << 24) & 0xff000000)
! 				| // 48, 32 bits
! 				(((int) data[49] << 16) & 0x00ff0000)
! 				| (((int) data[50] << 8) & 0x0000ff00)
! 				| ((int) data[51] & 0x000000ff);
! 
! 		nextPktPos = (((int) data[52] << 24) & 0xff000000)
! 				| // 52, 32 bits
! 				(((int) data[53] << 16) & 0x00ff0000)
! 				| (((int) data[54] << 8) & 0x0000ff00)
! 				| ((int) data[55] & 0x000000ff);
! 
! 		// System.out.println("Number of APID list items [" +
! 		// ((this.pktTrackerOffset - this.apidListOffset)/32) + "]");
! 		// as it stand now the nextPktPos should equal the data.length --
! 		// TESTING
! 		if (nextPktPos != data.length) {
! 			System.out.println(">> Warning: there is a nextPktPos["
! 					+ nextPktPos + "] data.length [" + data.length
! 					+ "] discrepency!!!");
! 		}
! 	}
! 
! 	/**
! 	 * Return a pointer to the original input data used for reading out the
! 	 * contents of the StaticHeader read out of the RawApplicationPackets area.
! 	 * 
! 	 * @return a byte array of the data
! 	 */
! 	public byte[] getData() {
! 		return this.data;
! 	}
! 
! 	/**
! 	 * Return the ApStorageOffset value
! 	 * 
! 	 * @return the offset
! 	 */
! 	public int getApStorageOffset() {
! 		return apStorageOffset;
! 	}
! 
! 	/**
! 	 * Return the total size of the StaticHeader which is the fixed sized of the
! 	 * StaticHeader area plus the RDR list size and the packet tracker size.
! 	 * 
! 	 * @return the sum of the sizes
! 	 */
! 	public int getTotalHeaderSize() {
! 		return HeaderSize + rdrList.getSize() + packetTracker.getSize();
! 	}
! 
! 	/**
! 	 * Return the packet store size
! 	 * 
! 	 * @return the size
! 	 */
! 	public int getPacketStoreSize() {
! 		return this.apStorageArea.getSize();
! 	}
! 
! 	/**
! 	 * Return the size of the StaticHeader, the RDR list size, the packet tacker
! 	 * size and the packet store size itself
! 	 * 
! 	 * @return the sum of all the sizes
! 	 */
! 	public int getSize() {
! 		return getTotalHeaderSize() + getPacketStoreSize();
! 	}
! 
! 	/**
! 	 * Return the AppIdList offset in the StaticHeader area
! 	 * 
! 	 * @return the offset
! 	 */
! 	public int getAppIdListOffset() {
! 		return this.apidListOffset;
! 	}
! 
! 	/**
! 	 * Return the packet tracker offset in the StaticHeader area
! 	 * 
! 	 * @return the offset
! 	 */
! 	public int getPktTrackerOffset() {
! 		return this.pktTrackerOffset;
! 	}
! 
! 	public int getNextPktPos() {
! 		return this.nextPktPos;
! 	}
! 
! 	/**
! 	 * Write from the various sources of input the StaticHeader and the packet
! 	 * storage area to the RawApplicationPackets based on the HDF DataSet
! 	 * handle.
! 	 * 
! 	 * @param dataSet
! 	 *            the HDF handle to the RawApplicationPackets
! 	 * @throws RtStpsException
! 	 *             wrapped HDF or other exceptions
! 	 */
! 	public void write(int dataSet) throws RtStpsException {
! 		// write static header fields
! 		this.dataSet = dataSet; // FIXME maybe, this could be passed into the
! 								// constructor...
! 
! 		// System.out.println("static header size: " + this.getSize());
! 		int neededSize = this.getSize();
! 		neededSize = ((neededSize / 1024) * 1024) + 1024;
! 
! 		// System.out.println("static header size: " + this.getSize() +
! 		// " Rounded up: " + neededSize + " bufsize: " + bufSize);
! 		if (neededSize > bufSize) {
! 			this.data = new byte[neededSize /* this.getSize() */]; // must be
! 																	// dynamically
! 																	// calculated
! 																	// depending
! 																	// on inputs
! 			bufSize = neededSize;
! 		}
! 
! 		writeSatellite();
! 
! 		writeSensor();
! 
! 		writeTypeID();
! 
! 		writeNumAppIds();
! 
! 		writeApidListOffset();
! 
! 		writePktTrackerOffset();
! 
! 		writeApStorageOffset();
! 
! 		writeNextPktPos();
! 
! 		writeStartBoundary(); // FIXME must be called first
! 
! 		writeEndBoundary();
! 
! 		offset = rdrList.write(data, offset);
! 
! 		offset = packetTracker.write(data, offset);
! 
! 		// writeApplicationStorageArea();
! 
! 		offset = apStorageArea.write(data, offset);
! 
! 		writeToHDF();
! 
! 		// this.data = null;
! 
! 	}
! 
! 	public String readSatelliteString() {
! 		String satellite = new String(data, 0, 4, Charset.forName("US-ASCII"))
! 				.trim();
! 		return satellite;
! 	}
! 
! 	/**
! 	 * Write the satellite name to the StaticHeader data buffer, converting it
! 	 * to ASCII first
! 	 */
! 	private void writeSatellite() {
! 
! 		// System.out.println("Satellite = " + satellite);
! 
! 		byte[] ascii = satellite.toString().getBytes(
! 				Charset.forName("US-ASCII"));
! 
! 		// System.out.println("ascii length = " + ascii.length);
! 
! 		// System.out.println("data length = " + data.length);
! 		data[offset++] = ascii[0];
! 		data[offset++] = ascii[1];
! 		data[offset++] = ascii[2];
! 		data[offset++] = 0;
! 
! 	}
! 
! 	public String readSensorString() {
! 		String sensor = new String(data, 4, 16, Charset.forName("US-ASCII"))
! 				.trim();
! 		return sensor;
! 	}
! 
! 	/**
! 	 * Write the sensor name to the StaticHeader data buffer, converting it to
! 	 * ASCII first
! 	 */
! 	private void writeSensor() {
! 		// System.out.println("rdrName.getSensor: " +
! 		// rdrName.getSensor().toString());
! 
! 		byte[] ascii = rdrName.getSensor().toString()
! 				.getBytes(Charset.forName("US-ASCII"));
! 
! 		// System.out.println("Sensor length: " + ascii.length);
! 
! 		for (int i = 0; i < 16; i++) {
! 			data[offset + i] = 0;
! 		}
! 		int copyLen = ascii.length;
! 		if (copyLen > 16)
! 			copyLen = 16;
! 
! 		for (int i = 0; i < copyLen; i++) {
! 			data[offset + i] = ascii[i];
! 		}
! 		offset += 16;
! 	}
! 
! 	public String readTypeIDString() {
! 		String typeID = new String(data, 20, 16, Charset.forName("US-ASCII"))
! 				.trim();
! 		return typeID;
! 	}
! 
! 	/**
! 	 * Write the type id name to the StaticHeader data buffer, converting it to
! 	 * ASCII first
! 	 */
! 	private void writeTypeID() {
! 
! 		// System.out.println("rdrName.getTypeID: " +
! 		// rdrName.getTypeID().toString());
! 
! 		byte[] ascii = rdrName.getTypeID().toString()
! 				.getBytes(Charset.forName("US-ASCII"));
! 
! 		// System.out.println("TypeId length: " + ascii.length);
! 
! 		for (int i = 0; i < 16; i++) {
! 			data[offset + i] = 0;
! 		}
! 		int copyLen = ascii.length;
! 		if (copyLen > 16)
! 			copyLen = 16;
! 
! 		for (int i = 0; i < copyLen; i++) {
! 			data[offset + i] = ascii[i];
! 		}
! 		offset += 16;
! 	}
! 
! 	public int readNumAppIds() {
! 		int numAppIds = ((int) data[36] << 24)
! 				| (((int) data[37] << 16) & 0x00ff0000)
! 				| (((int) data[38] << 8) & 0x0000ff00)
! 				| ((int) data[39] & 0x000000ff);
! 		return numAppIds;
! 	}
! 
! 	/**
! 	 * Write the number of application IDs to the StaticHeader data buffer
! 	 */
! 	private void writeNumAppIds() {
! 		// numAppIds = rdrName.getNumberOfAppIdsInRDR();
! 		data[offset++] = (byte) ((numAppIds >>> 24) & 0x0ff);
! 		data[offset++] = (byte) ((numAppIds >>> 16) & 0x0ff);
! 		data[offset++] = (byte) ((numAppIds >>> 8) & 0x0ff);
! 		data[offset++] = (byte) (numAppIds & 0x0ff);
! 
! 	}
! 
! 	public long readApidListOffset() {
! 		int apidListOffset = ((int) data[40] << 24)
! 				| (((int) data[41] << 16) & 0x00ff0000)
! 				| (((int) data[42] << 8) & 0x0000ff00)
! 				| ((int) data[43] & 0x000000ff);
! 		return apidListOffset;
! 	}
! 
! 	/**
! 	 * Write the application ID list offset to the StaticHeader data buffer
! 	 */
! 	private void writeApidListOffset() {
! 
! 		data[offset++] = (byte) ((apidListOffset >>> 24) & 0x0ff);
! 		data[offset++] = (byte) ((apidListOffset >>> 16) & 0x0ff);
! 		data[offset++] = (byte) ((apidListOffset >>> 8) & 0x0ff);
! 		data[offset++] = (byte) (apidListOffset & 0x0ff);
! 
! 	}
! 
! 	public RDRAppIdList readRDRAppIdList() {
! 
! 		return new RDRAppIdList((int) readApidListOffset(), data,
! 				(int) readPktTrackerOffset());
! 	}
! 
! 	public long readPktTrackerOffset() {
! 		int pktTrackerOffset = ((int) data[44] << 24)
! 				| (((int) data[45] << 16) & 0x00ff0000)
! 				| (((int) data[46] << 8) & 0x0000ff00)
! 				| ((int) data[47] & 0x000000ff);
! 		return pktTrackerOffset;
! 	}
! 
! 	/**
! 	 * Write the packet tracker offset to the StaticHeader data buffer
! 	 */
! 	private void writePktTrackerOffset() {
! 
! 		data[offset++] = (byte) ((pktTrackerOffset >>> 24) & 0x0ff);
! 		data[offset++] = (byte) ((pktTrackerOffset >>> 16) & 0x0ff);
! 		data[offset++] = (byte) ((pktTrackerOffset >>> 8) & 0x0ff);
! 		data[offset++] = (byte) (pktTrackerOffset & 0x0ff);
! 
! 	}
! 
! 	public long readApStorageOffset() {
! 		int apStorageOffset = ((int) data[48] << 24)
! 				| (((int) data[49] << 16) & 0x00ff0000)
! 				| (((int) data[50] << 8) & 0x0000ff00)
! 				| ((int) data[51] & 0x000000ff);
! 		return apStorageOffset;
! 	}
! 
! 	/**
! 	 * Write the ap storage offset to the StaticHeader data buffer
! 	 */
! 	private void writeApStorageOffset() {
! 		// System.out.println("Creating storage offset at offset: " + offset +
! 		// " value of it: " + apStorageOffset);
! 		data[offset++] = (byte) ((apStorageOffset >>> 24) & 0x0ff);
! 		data[offset++] = (byte) ((apStorageOffset >>> 16) & 0x0ff);
! 		data[offset++] = (byte) ((apStorageOffset >>> 8) & 0x0ff);
! 		data[offset++] = (byte) (apStorageOffset & 0x0ff);
! 
! 		// System.out.println("offset now = " + offset);
! 
! 	}
! 
! 	public long readNextPktPos() {
! 		int nextPktPos = ((int) data[52] << 24)
! 				| (((int) data[53] << 16) & 0x00ff0000)
! 				| (((int) data[54] << 8) & 0x0000ff00)
! 				| ((int) data[55] & 0x000000ff);
! 		return nextPktPos;
! 	}
! 
! 	/**
! 	 * Write the next packet position to the StaticHeader data buffer
! 	 */
! 	private void writeNextPktPos() {
! 		data[offset++] = (byte) ((nextPktPos >>> 24) & 0x0ff);
! 		data[offset++] = (byte) ((nextPktPos >>> 16) & 0x0ff);
! 		data[offset++] = (byte) ((nextPktPos >>> 8) & 0x0ff);
! 		data[offset++] = (byte) (nextPktPos & 0x0ff);
! 
! 	}
! 
! 	public long readStartBoundary() {
! 		long startBoundary = 0L;
! 		int loffset = 56;
! 		startBoundary = ((long) data[loffset++] << 56) & 0xff00000000000000l;
! 		startBoundary |= ((long) data[loffset++] << 48) & 0x00ff000000000000l;
! 		startBoundary |= ((long) data[loffset++] << 40) & 0x0000ff0000000000l;
! 		startBoundary |= ((long) data[loffset++] << 32) & 0x000000ff00000000l;
! 		startBoundary |= ((long) data[loffset++] << 24) & 0x00000000ff000000l;
! 		startBoundary |= ((long) data[loffset++] << 16) & 0x0000000000ff0000l;
! 		startBoundary |= ((long) data[loffset++] << 8) & 0x000000000000ff00l;
! 		startBoundary |= (long) data[loffset++] & 0x00000000000000ffl;
! 
! 		return startBoundary;
! 	}
! 
! 
! 
! 	// end FIXME SSEC
! 
! 	/**
! 	 * Write the start boundary to the StaticHeader data buffer
! 	 */
! 	private void writeStartBoundary() {
! 		Packet firstPacket = getFirstPacketWithTimestamp(rdrName);
! 		// we don't check for non-null result... assume that's fatal issue right
! 		// now that needs to be checked
! 
! 		// System.out.println("First packet end boundary: " +
! 		// PDSDate.getMicrosSinceEpoch(firstPacket.getTimeStamp(8)));
! 
! 		// startBoundary =
! 		// PDSDate.getMicrosSinceEpoch(firstPacket.getTimeStamp(8));
! 		long ietTime = 0L;
! 		
! 		LeapDate lpd = new LeapDate(firstPacket.getTimeStamp(8));
! 		ietTime = lpd.getMicrosSinceEpoch();
! 
! 		
! 
! 		startBoundary = ietTime;
! 
! 		startBoundary = GranuleId.calcGranuleStartTime(ietTime, rdrName);
! 
! 		// VIIRS partial test
! 		// if (rdrName == RDRName.VIIRS_Science) {
! 		// startBoundary = 1422168873750000L; // was just ietTime
! 		// }
! 
! 		data[offset++] = (byte) ((startBoundary >>> 56) & 0x0ffL);
! 		data[offset++] = (byte) ((startBoundary >>> 48) & 0x0ffL);
! 		data[offset++] = (byte) ((startBoundary >>> 40) & 0x0ffL);
! 		data[offset++] = (byte) ((startBoundary >>> 32) & 0x0ffL);
! 		data[offset++] = (byte) ((startBoundary >>> 24) & 0x0ffL);
! 		data[offset++] = (byte) ((startBoundary >>> 16) & 0x0ffL);
! 		data[offset++] = (byte) ((startBoundary >>> 8) & 0x0ffL);
! 		data[offset++] = (byte) (startBoundary & 0x0ffL);
! 
! 	}
! 
! 	// there an assumption there will be one, otherwise this ultimately will
! 	// result in a
! 	// null pointer exception where used...
! 
! 	private Packet getFirstPacketWithTimestamp(RDRName myRdrName) {
! 		for (Packet p : packetList) {
! //			if (p.hasSecondaryHeader()) {
! 				// do some quick checks
  
! 				LPEATEDate lpd = new LPEATEDate(p.getTimeStamp(8));
! 				long ietTime = lpd.getMicrosSinceEpoch();
  
! 				long st = GranuleId.calcGranuleStartTime(ietTime, myRdrName);
  
  
! 				if (st > 0) {
! 					System.out.println("Boundry: "+ st + " name "+myRdrName);
! 					return p;
! 				}
! //			}
  		}
+ 		return null;
+ 	}
  
! 	public long readEndBoundary() {
! 		long endBoundary = 0L;
! 		int loffset = 64;
! 		endBoundary = ((long) data[loffset++] << 56) & 0xff00000000000000l;
! 		endBoundary |= ((long) data[loffset++] << 48) & 0x00ff000000000000l;
! 		endBoundary |= ((long) data[loffset++] << 40) & 0x0000ff0000000000l;
! 		endBoundary |= ((long) data[loffset++] << 32) & 0x000000ff00000000l;
! 		endBoundary |= ((long) data[loffset++] << 24) & 0x00000000ff000000l;
! 		endBoundary |= ((long) data[loffset++] << 16) & 0x0000000000ff0000l;
! 		endBoundary |= ((long) data[loffset++] << 8) & 0x000000000000ff00l;
! 		endBoundary |= (long) data[loffset++] & 0x00000000000000ffl;
! 
! 		return endBoundary;
! 	}
! 
! 	/**
! 	 * Write the end boundary to the StaticHeader data buffer
! 	 */
! 	private void writeEndBoundary() {
  
! 		Packet lastPacket = getLastPacketWithTimestamp();
  
! 		Packet firstPacket = getFirstPacketWithTimestamp(rdrName);
  
! 		long ietTime = 0L;
  		
  	
  
  	
! 		LeapDate lpd = new LeapDate(firstPacket.getTimeStamp(8));
! 		ietTime = lpd.getMicrosSinceEpoch();
  		
  		
  
+ 		endBoundary = ietTime;
  
+ 		endBoundary = GranuleId.calcGranuleEndTime(ietTime, rdrName);
+ 		// VIIRS partial test
+ 		// if (rdrName == RDRName.VIIRS_Science) {
+ 		// endBoundary = 1422168959100000L;
+ 		// }
+ 
+ 		data[offset++] = (byte) ((endBoundary >>> 56) & 0x0ffL);
+ 		data[offset++] = (byte) ((endBoundary >>> 48) & 0x0ffL);
+ 		data[offset++] = (byte) ((endBoundary >>> 40) & 0x0ffL);
+ 		data[offset++] = (byte) ((endBoundary >>> 32) & 0x0ffL);
+ 		data[offset++] = (byte) ((endBoundary >>> 24) & 0x0ffL);
+ 		data[offset++] = (byte) ((endBoundary >>> 16) & 0x0ffL);
+ 		data[offset++] = (byte) ((endBoundary >>> 8) & 0x0ffL);
+ 		data[offset++] = (byte) (endBoundary & 0x0ffL);
+ 
+ 	}
+ 
+ 	/**
+ 	 * private void writeApplicationStorageArea() throws HDF5LibraryException,
+ 	 * NullPointerException {
+ 	 * System.out.println("Counter basedd Offset into storage area: " + offset);
+ 	 * for (Packet p : packetList) { System.out.println("p.getSize()" +
+ 	 * p.getSize()); writeBytes(p.getData(), p.getSize()); }
+ 	 * 
+ 	 * }
+ 	 * 
+ 	 * private void writeBytes(byte[] from, int size) { for (int i = 0; i <
+ 	 * size; i++) { this.data[offset++] = from[i]; } }
+ 	 * 
+ 	 * @throws RtStpsException
+ 	 **/
+ 
+ 	// there an assumption there will be one, otherwise this ultimately will
+ 	// result in a
+ 	// null pointer exception where used...
+ 
+ 	private Packet getLastPacketWithTimestamp() {
+ 		int end = packetList.size() - 1;
+ 
+ 		// for larger granules this could be worth it
+ 		for (int i = end; i >= 0; i--) {
+ 
+ 			Packet p = packetList.get(i);
+ 			if (p.hasSecondaryHeader()) {
+ 				return p;
+ 			}
+ 		}
+ 		return null;
+ 	}
+ 
+ 	/**
+ 	 * Write the entire filled out data buffer to the HDF file at the specified
+ 	 * DataSet handle using the data buffer array
+ 	 * 
+ 	 * @exception wraps
+ 	 *                any HDF exceptions in an RtStpsException
+ 	 */
+ 	private void writeToHDF() throws RtStpsException {
+ 		try {
+ 			H5.H5Dwrite(dataSet, HDF5Constants.H5T_STD_U8BE,
+ 					HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
+ 					HDF5Constants.H5P_DEFAULT, data);
+ 		} catch (HDF5LibraryException e) {
+ 			throw new RtStpsException(e);
+ 		}
+ 	}
  
  }
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/VIIRSRawApplicationPackets2.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/VIIRSRawApplicationPackets2.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/VIIRSRawApplicationPackets2.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/VIIRSRawApplicationPackets2.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 2,27 ****
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
! */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
- 
- 
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
  import gov.nasa.gsfc.drl.rtstps.core.ccsds.Packet;
  import ncsa.hdf.hdf5lib.exceptions.HDF5LibraryException;
  
  /**
!  * Build VIIRS [@link RawApplicationPackets} by capturing groups scan packets between packet with
!  * and application ID of 800 with a secondary header timestamp.  The first group captured is likely going to be short due
!  * to the fact that frame lock could occur at any time.  Scans groups that form a granule are specified
!  * externally in the constructor.
   * 
   * 
-  *
   */
  
! // FIXME this one does not work well on the Orbit2 dateset which seems to have a long stretch of bad scans resulting
  // in the accumulation of a large number of unrelated packets...
  @Deprecated
  public class VIIRSRawApplicationPackets2 extends RawApplicationPackets {
--- 2,27 ----
  Copyright (c) 1999-2007, United States Government, as represented by
  the Administrator for The National Aeronautics and Space Administration.
  All rights reserved.
!  */
  package gov.nasa.gsfc.drl.rtstps.core.output.rdr;
  
  import gov.nasa.gsfc.drl.rtstps.core.RtStpsException;
  import gov.nasa.gsfc.drl.rtstps.core.ccsds.Packet;
  import ncsa.hdf.hdf5lib.exceptions.HDF5LibraryException;
  
  /**
!  * Build VIIRS [@link RawApplicationPackets} by capturing groups scan packets
!  * between packet with and application ID of 800 with a secondary header
!  * timestamp. The first group captured is likely going to be short due to the
!  * fact that frame lock could occur at any time. Scans groups that form a
!  * granule are specified externally in the constructor.
!  * 
   * 
   * 
   */
  
! // FIXME this one does not work well on the Orbit2 dateset which seems to have a
! // long stretch of bad scans resulting
  // in the accumulation of a large number of unrelated packets...
  @Deprecated
  public class VIIRSRawApplicationPackets2 extends RawApplicationPackets {
***************
*** 29,207 ****
  	private Stats stats = null;
  	private int scanCount = 0;
  	private int sciPacketCount = 0;
! 	
  	/**
  	 * Constructor to initialize the RawApplicationPackets algorithm for VIIRS.
! 	 * @param satellite the satellite ID as defined by the mission documents
! 	 * @param setNum the set number which is appended to the end of each RawApplicationPacket in the HDF
! 	 * @param scansPerGranule The number of scans to collect to make one granule
  	 */
! 	public VIIRSRawApplicationPackets2(SpacecraftId satellite, int setNum, int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.VIIRS_Science, setNum, packetPool);
! 		
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
! 		
! 		
! 		
  	}
! 	
! 	public VIIRSRawApplicationPackets2(Stats stats, SpacecraftId satellite, int setNum, int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.VIIRS_Science, setNum, packetPool);
! 		
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
! 		
! 	
  		this.stats = stats;
  	}
  
- 	
- 	
  	/**
! 	 * Constructor which attempts to read the RawApplicationPacket entry that pre-exists.
! 	 * The contents of the dataspace are read into a memory buffer... assuming it will fit.
! 	 * @param allRDRId  the rdrAll Groups id
! 	 * @param setNum the set number of raw entry
! 	 * @throws RtStpsException 
! 	 * @throws NullPointerException 
! 	 * @throws HDF5LibraryException 
  	 */
! 	public VIIRSRawApplicationPackets2(int allRDRId, int setNum) throws RtStpsException {
  		super(allRDRId, setNum);
  	}
! 	
! 	public VIIRSRawApplicationPackets2(int readId, int setNum, boolean usedByGranuleOnly) throws RtStpsException {
  		super(readId, setNum, true);
  	}
  
  	/**
! 	 * Granules are created from scans.  Scans in VIIRS are lots of packets the first 800 w/with a 
! 	 * secondaryheader is used here to signal the start of a scan.   We collect it and everything after it
! 	 * as one scan until it re-appears.  Anything more complex than this can be built on top of this
  	 * one assumption.
  	 * 
! 	 * @param p  a Packet to be put into the VIIRS RawApplicationPackets area
! 	 * @return true if it can be put there, or false if it is full and should be written to disk first
! 	 * @exception wraps any HDF exceptions in RtStpsException
  	 */
  	public boolean notFull(Packet p) throws RtStpsException {
! 		
  		// every appearance of first 800 w/secondary header means start of scan
  		boolean state = true;
! 		
! 		if (p.isFirstPacketInSequence() && p.hasSecondaryHeader()) {
! 			if (p.getApplicationId() == 800) {
! 				
! 						if ((scanCount + 1) > scansPerGranule) {
! 							state = false; // it's full in otherwords
! 						
  						} else {
  							++scanCount;
  						}
! 						//System.out.println("VIIRs Current scan count -- " + scanCount);
! 						
! 					
  			}
  		}
! 		return state;  // true == not full, false == full
! 		
  
  	}
! 	
! 	
! 	
! 	/**
! 	 * Put the packet into the VIIRSRawApplications area, the method <code>notFull</code> should
! 	 * have been called first to check if this is allowed or not.
! 	 * @param p a Packet to put into it
! 	 * @exception wraps any HDF exceptions in RtStpsException
  	 */
  	public void put(Packet p) throws RtStpsException {
! 		if (scanCount <= 0) { // throw away any initial packets if we've not seen the start of a scan...
! 			if (stats == null) {
! 				System.out.println("Trimming VIIRS [" + p.getApplicationId() + "]");
! 			} else {
! 				//stats.sci_trimmedPackets.value++;
! 			}
! 			return;
! 		}
  		sciPacketCount++;
! 		
  		this.updateAppIdCounters(p.getApplicationId());
! 		
  		RDRName rdrName = RDRName.fromAppId(p.getApplicationId());
! 		
  		if (rdrName != RDRName.VIIRS_Science) {
! 			throw new RtStpsException("Not a VIIRS science packet [" + p.getApplicationId() + "]");
  		}
  
  		// collect time info
  		if (p.hasSecondaryHeader()) {
  
! 			// secondary time stamp only valid in in first or standalone packets...
! 			if (getFirstTime() == 0L) {
! 				//System.out.println("Here...");
! 				setFirstTime(p.getTimeStamp(8));
! 			}
! 			
! 			setLastTime(p.getTimeStamp(8));
  		}
  		Packet pcopy = CopyPacket.deep(p, packetPool);
  		getPacketList().add(pcopy);
  	}
! 	
  	/**
! 	 * Write the accumulate packets to the RDR/HDF file.  Note that this method
! 	 * must be used in conjunction with method <code>notFull</code> and <code>put</code>.
! 	 * @param hdfFile the handle to the RDR/HDF file that the packets should written to
  	 * @return true if the write succeeded
! 	 * @exception wraps any HDF exceptions in RtStpsException
  	 */
! 	public boolean write(int hdfFile) throws RtStpsException  {
! 		
! 		boolean ret = true;
! 		if (this.scanCount < this.scansPerGranule) {
  
! 			if (stats == null) {
! 				System.out.println("Deleting partial VIIRS Granule -- [" + scanCount + "] scans");
! 			} else {
! 				stats.sci_discardedGranules.value++;
! 			}
! 
! 			ret = false;
  		} else {
  
! 			if (stats == null) {
! 				System.out.println("Creating VIIRS Granule with [" + scanCount + "] scans");
! 			} else {
! 				stats.sci_createdGranules.value++;
! 			}
  
! 			ret = super.write(hdfFile);
! 		}
! 		
! 		System.out.println(">> VIIRS Sci packets in granule: " + sciPacketCount + " Packet per scan: " + (float)sciPacketCount / (float)scansPerGranule);
  		scanCount = 0;
! 		
  		sciPacketCount = 0;
! 		
  		return ret;
  	}
  
  	/**
! 	 * Close the RDR/HDF file specifically for the RawApplicationsPackets.  This method should be 
! 	 * called once specific RawApplicationPacket_x has been written. 
! 	 * @exception wraps any HDF exceptions in RtStpsException
  	 */
! 	public void close() throws RtStpsException  {
  		super.close();
  		scanCount = 0;
! 		
  		sciPacketCount = 0;
  	}
  
- 
  }
--- 29,306 ----
  	private Stats stats = null;
  	private int scanCount = 0;
  	private int sciPacketCount = 0;
! 
  	/**
  	 * Constructor to initialize the RawApplicationPackets algorithm for VIIRS.
! 	 * 
! 	 * @param satellite
! 	 *            the satellite ID as defined by the mission documents
! 	 * @param setNum
! 	 *            the set number which is appended to the end of each
! 	 *            RawApplicationPacket in the HDF
! 	 * @param scansPerGranule
! 	 *            The number of scans to collect to make one granule
  	 */
! 	public VIIRSRawApplicationPackets2(SpacecraftId satellite, int setNum,
! 			int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.VIIRS_Science, setNum, packetPool);
! 
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
! 
  	}
! 
! 	public VIIRSRawApplicationPackets2(Stats stats, SpacecraftId satellite,
! 			int setNum, int scansPerGranule, PacketPool packetPool) {
  		super(satellite, RDRName.VIIRS_Science, setNum, packetPool);
! 
  		if (setNum < 0) {
  			throw new IllegalArgumentException("Illegal Index [" + setNum + "]");
  		}
! 
  		this.stats = stats;
  	}
  
  	/**
! 	 * Constructor which attempts to read the RawApplicationPacket entry that
! 	 * pre-exists. The contents of the dataspace are read into a memory
! 	 * buffer... assuming it will fit.
! 	 * 
! 	 * @param allRDRId
! 	 *            the rdrAll Groups id
! 	 * @param setNum
! 	 *            the set number of raw entry
! 	 * @throws RtStpsException
! 	 * @throws NullPointerException
! 	 * @throws HDF5LibraryException
  	 */
! 	public VIIRSRawApplicationPackets2(int allRDRId, int setNum)
! 			throws RtStpsException {
  		super(allRDRId, setNum);
  	}
! 
! 	public VIIRSRawApplicationPackets2(int readId, int setNum,
! 			boolean usedByGranuleOnly) throws RtStpsException {
  		super(readId, setNum, true);
  	}
  
+ 	// /**
+ 	// * Granules are created from scans. Scans in VIIRS are lots of packets the
+ 	// first 800 w/with a
+ 	// * secondaryheader is used here to signal the start of a scan. We collect
+ 	// it and everything after it
+ 	// * as one scan until it re-appears. Anything more complex than this can be
+ 	// built on top of this
+ 	// * one assumption.
+ 	// *
+ 	// * @param p a Packet to be put into the VIIRS RawApplicationPackets area
+ 	// * @return true if it can be put there, or false if it is full and should
+ 	// be written to disk first
+ 	// * @exception wraps any HDF exceptions in RtStpsException
+ 	// */
+ 	// public boolean notFull(Packet p) throws RtStpsException {
+ 	//
+ 	// // every appearance of first 800 w/secondary header means start of scan
+ 	// boolean state = true;
+ 	//
+ 	// if (p.isFirstPacketInSequence() && p.hasSecondaryHeader()) {
+ 	// if (p.getApplicationId() == 800) {
+ 	//
+ 	// if ((scanCount + 1) > scansPerGranule) {
+ 	// state = false; // it's full in otherwords
+ 	//
+ 	// } else {
+ 	// ++scanCount;
+ 	// }
+ 	// //System.out.println("VIIRs Current scan count -- " + scanCount);
+ 	//
+ 	//
+ 	// }
+ 	// }
+ 	// return state; // true == not full, false == full
+ 	//
+ 	//
+ 	// }
+ 
+ 	static long firstTime = -1;
+ 
  	/**
! 	 * Granules are created from scans. Scans in VIIRS are lots of packets the
! 	 * first 800 w/with a secondaryheader is used here to signal the start of a
! 	 * scan. We collect it and everything after it as one scan until it
! 	 * re-appears. Anything more complex than this can be built on top of this
  	 * one assumption.
  	 * 
! 	 * @param p
! 	 *            a Packet to be put into the VIIRS RawApplicationPackets area
! 	 * @return true if it can be put there, or false if it is full and should be
! 	 *         written to disk first
! 	 * @exception wraps
! 	 *                any HDF exceptions in RtStpsException
  	 */
  	public boolean notFull(Packet p) throws RtStpsException {
! 
  		// every appearance of first 800 w/secondary header means start of scan
  		boolean state = true;
! 
! 		if (p.hasSecondaryHeader()) {
! 			// if (p.getApplicationId() == 800)
! 			{
! 				// idea is we allow apid=0 and 8 in but only check for fullness
! 				// on apid=11
! 				long timestamp = p.getTimeStamp(8);
! 
! 				GranuleId currentGranId = new GranuleId(SpacecraftId.npp,
! 						p.getTimeStamp(8),
! 						RDRName.VIIRS_Science);
! 
! 				LeapDate obsTime = new LeapDate(timestamp);
! 				// System.out.printf("VIIRS: Gran %s seq %d ts %d obs %d \n",
! 				// currentGranId.toString(), p.getSequenceCounter(),
! 				// timestamp, obsTime.getMicrosSinceEpoch());
! 
! 				if (currentGranId.toString().startsWith("NPP-") == false) {
! 
! 					if (this.firstTime < 0l) {
! 						this.firstTime = timestamp;
! 						setFirstTime(timestamp);
! 					} else {
! 
! 						GranuleId startGranId = new GranuleId(SpacecraftId.npp,
! 								getFirstTime(),
! 								RDRName.VIIRS_Science);
! 
! 						if (startGranId.toString().contentEquals(
! 								currentGranId.toString()) == false) {
! 							firstTime = -1;
! 							System.out.println("VIIRS GRAN Start: "
! 									+ startGranId.toString() + " Current:"
! 									+ currentGranId.toString());
! 
! 							System.out.println("New Granule" + scanCount);
! 							state = false;
  						} else {
  							++scanCount;
+ 							setLastTime(p.getTimeStamp(8));
  						}
! 
! 					}
! 				}
  			}
  		}
! 		return state; // true == not full, false == full
  
  	}
! 
! 	/**
! 	 * Put the packet into the VIIRSRawApplications area, the method
! 	 * <code>notFull</code> should have been called first to check if this is
! 	 * allowed or not.
! 	 * 
! 	 * @param p
! 	 *            a Packet to put into it
! 	 * @exception wraps
! 	 *                any HDF exceptions in RtStpsException
  	 */
  	public void put(Packet p) throws RtStpsException {
! //		if (scanCount <= 0) { // throw away any initial packets if we've not
! //								// seen the start of a scan...
! //			if (stats == null) {
! //				System.out.println("Trimming VIIRS [" + p.getApplicationId()
! //						+ "]");
! //			} else {
! //				// stats.sci_trimmedPackets.value++;
! //			}
! //			return;
! //		}
  		sciPacketCount++;
! 
  		this.updateAppIdCounters(p.getApplicationId());
! 
  		RDRName rdrName = RDRName.fromAppId(p.getApplicationId());
! 
  		if (rdrName != RDRName.VIIRS_Science) {
! 			throw new RtStpsException("Not a VIIRS science packet ["
! 					+ p.getApplicationId() + "]");
  		}
  
  		// collect time info
  		if (p.hasSecondaryHeader()) {
  
! 			// secondary time stamp only valid in in first or standalone
! 			// packets...
! //			if (getFirstTime() == 0L) {
! //				// System.out.println("Here...");
! //				setFirstTime(p.getTimeStamp(8));
! //			}
! 
! //			setLastTime(p.getTimeStamp(8));
  		}
  		Packet pcopy = CopyPacket.deep(p, packetPool);
  		getPacketList().add(pcopy);
  	}
! 
  	/**
! 	 * Write the accumulate packets to the RDR/HDF file. Note that this method
! 	 * must be used in conjunction with method <code>notFull</code> and
! 	 * <code>put</code>.
! 	 * 
! 	 * @param hdfFile
! 	 *            the handle to the RDR/HDF file that the packets should written
! 	 *            to
  	 * @return true if the write succeeded
! 	 * @exception wraps
! 	 *                any HDF exceptions in RtStpsException
  	 */
! 	public boolean write(int hdfFile) throws RtStpsException {
  
! 		boolean ret = true;
! 		// if (this.scanCount < this.scansPerGranule) {
! 		//
! 		// if (stats == null) {
! 		// System.out.println("Deleting partial VIIRS Granule -- ["
! 		// + scanCount + "] scans");
! 		// } else {
! 		// stats.sci_discardedGranules.value++;
! 		// }
! 		//
! 		// ret = false;
! 		// } else {
! 
! 		if (stats == null) {
! 			System.out.println("Creating VIIRS Granule with [" + scanCount
! 					+ "] scans");
  		} else {
+ 			stats.sci_createdGranules.value++;
+ 		}
  
! 		ret = super.write(hdfFile);
! 		// }
  
! 		System.out.println(">> VIIRS Sci packets in granule: " + sciPacketCount
! 				+ " Packet per scan: " + (float) sciPacketCount
! 				/ (float) scansPerGranule);
  		scanCount = 0;
! 
  		sciPacketCount = 0;
! 
  		return ret;
  	}
  
  	/**
! 	 * Close the RDR/HDF file specifically for the RawApplicationsPackets. This
! 	 * method should be called once specific RawApplicationPacket_x has been
! 	 * written.
! 	 * 
! 	 * @exception wraps
! 	 *                any HDF exceptions in RtStpsException
  	 */
! 	public void close() throws RtStpsException {
  		super.close();
  		scanCount = 0;
! 
  		sciPacketCount = 0;
  	}
  
  }
diff -crB rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/VIIRS_RDR_MultiGranule.java rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/VIIRS_RDR_MultiGranule.java
*** rt-stps-org/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/VIIRS_RDR_MultiGranule.java	2011-12-19 11:21:55.000000000 -0800
--- rt-stps/src/gov/nasa/gsfc/drl/rtstps/core/output/rdr/VIIRS_RDR_MultiGranule.java	2012-03-08 15:33:29.000000000 -0800
***************
*** 53,59 ****
  		RawApplicationPackets rap;
  		
  
! 		rap = new VIIRSRawApplicationPackets_MultiGranule(stats, SpacecraftId.npp, getSetNum(), scansPerGranule, getPacketPool());			
  	
  		
  		this.getRaps().push(rap);
--- 53,59 ----
  		RawApplicationPackets rap;
  		
  
! 		rap = new VIIRSRawApplicationPackets2(stats, SpacecraftId.npp, getSetNum(), scansPerGranule, getPacketPool());			
  	
  		
  		this.getRaps().push(rap);
