Index: /trunk/htdocs2/Classes/Model/ObservationSet.php
===================================================================
--- /trunk/htdocs2/Classes/Model/ObservationSet.php	(revision 406)
+++ /trunk/htdocs2/Classes/Model/ObservationSet.php	(revision 407)
@@ -4,4 +4,5 @@
 
 require_once 'Classes/Model/Observation.php';
+require_once 'Classes/Pulsar/ObservationData2.php';
 
 
@@ -35,5 +36,5 @@
       $this->calibrations[] = new Calibration( $next_cal );
 
-    $this->observation_data = new ObservationData( $rhs->observation_data );
+    $this->observation_data = new ObservationData2( $rhs->observation_data );
   }
 
@@ -45,5 +46,28 @@
   
   //! Get the adjusted filename, this will include scrunching parameters if set
-  public function GetDataFile()
+  public function GetDataFile() { return $this->priv_GetDataFile(); }
+  
+  public function SetScrunchingParameters( ScrunchingParameters $s_scr_params ) { $this->priv_SetScrunchingParameters( $s_scr_params ); }
+  
+  public function GetScrunchingParameters() { return $this->observation_data->GetScrunchingParameters(); }
+  
+  public function SetupObservationData() { $this->priv_SetupObservationData(); }
+  
+  public function EstimateDownloadableSize() { return $this->priv_EstimateDownloadableSize(); }
+  
+  public function MakeSourceFile() { $this->priv_MakeSourcefile(); }
+  
+  public function MakeDownloadables() { $this->priv_MakeDownloadables(); }
+  
+  public function GetDownloadFiles() { return $this->priv_GetDownloadFiles(); }
+  
+  // PRIVATE
+
+  private $observation;
+  private $calibrations;
+  private $observation_data;
+  private $data_dir;
+  
+  private function priv_GetDataFile()
   {
     if( $this->observation_data != null )
@@ -55,29 +79,30 @@
   }
   
-  public function SetScrunchingParameters( ScrunchingParameters $s_scrunching_parameters ) 
+  private function priv_SetScrunchingParameters( $s_scr_params )
   {
-    $this->observation_data->SetScrunchingParameters( $s_scrunching_parameters );
+    $this->observation_data->SetScrunchingParameters( $s_scr_params );
   }
   
-  public function GetScrunchingParameters() { return $this->observation_data->GetScrunchingParameters(); }
-  
   //! This function creates the observation_data object and sets it up
-  public function SetupObservationData()
+  private function priv_SetupObservationData()
   {
-    $this->observation_data = new ObservationData();
-    $this->observation_data->SetPath( $this->observation->GetFile() );
-    $this->observation_data->SetNBin( $this->observation->GetNBin() );
-    $this->observation_data->SetNPol( $this->observation->GetNPol() );
-    $this->observation_data->SetNChan( $this->observation->GetNChan() );
-    $this->observation_data->SetNSub( $this->observation->GetNSub() );
+    $this->observation_data = new ObservationData2();
+    $this->observation_data->SetObservationHeader( $this->observation );
+//     $this->observation_data->SetNBin( $this->observation->GetNBin() );
+//     $this->observation_data->SetNPol( $this->observation->GetNPol() );
+//     $this->observation_data->SetNChan( $this->observation->GetNChan() );
+//     $this->observation_data->SetNSub( $this->observation->GetNSub() );
     $this->observation_data->SetDataDir( $this->data_dir );
   }
   
-  public function EstimateDownloadableSize()
+  private function priv_EstimateDownloadableSize()
   {
     $dl_size = $this->observation_data->EstimateDownloadableSize();
+    
+    $estimater = new ObservationData2();
     foreach( $this->calibrations as $next_cal )
     {
-      $dl_size += $next_cal->GetFile()->GetFileSize();
+      $estimater->SetObservationHeader( $next_cal );
+      $dl_size += $estimater->EstimateDownloadableSize();
     }
 
@@ -86,11 +111,11 @@
   
   //! Make the source file, don't need the full downloadable files if we are plotting
-  public function MakeSourceFile()
+  private function priv_MakeSourceFile()
   {
-    $this->observation_data->MakeSourceFile();
+    $this->observation_data->GetDataFile();
   }
   
   
-  public function MakeDownloadables()
+  private function priv_MakeDownloadables()
   {
     $this->observation_data->MakeDownloadableFile();
@@ -100,9 +125,21 @@
       $dest_file = File::ConvertFullPath( $this->data_dir->GetPath() . '/' . $src_file->GetFilename() );
       if( !$dest_file->Exists() )
-        symlink( $src_file->GetFullPath(), $dest_file->GetFullPath() );
+      {
+        if( $src_file->Exists() && !$src_file->IsDir() )
+        {
+          symlink( $src_file->GetFullPath(), $dest_file->GetFullPath() );
+        }
+        else
+        {
+          $new_data = new ObservationData2();
+          $new_data->SetObservationHeader( $next_cal );
+          $new_data->SetDataDir( $this->data_dir );
+          $new_data->MakeDownloadableFile();
+        }
+      }
     }
   }
   
-  public function GetDownloadFiles()
+  private function priv_GetDownloadFiles()
   {
     $data_files = Array();
@@ -117,10 +154,4 @@
   }
 
-  // PRIVATE
-
-  private $observation;
-  private $calibrations;
-  private $observation_data;
-  private $data_dir;
 };
 
Index: /trunk/htdocs2/Classes/Pulsar/ObservationData.php
===================================================================
--- /trunk/htdocs2/Classes/Pulsar/ObservationData.php	(revision 406)
+++ /trunk/htdocs2/Classes/Pulsar/ObservationData.php	(revision 407)
@@ -11,9 +11,10 @@
 /**
  * @class ObservationData
- * 
- * This class represents the data from a single observation, on disk
- * this is one or more archives. We use this interface to create a standard
- * way of querying to see how large the file will be with or without
- * scrunching.
+ *
+ * This class represents the data from a single observation. This class can
+ * return or produce if needed any of the following files
+ * - original source file or directory
+ * - source file (if the original source was a directory it is psradded to make a single file)
+ * - scrunched file
  **/
 class ObservationData
@@ -229,6 +230,6 @@
     {
       $new_archive = new Archive();
-	$new_archive->SetPath( $this->path->GetPath() );
-	$new_archive->SetFilename( $this->path->GetFilename() );
+      $new_archive->SetPath( $this->path->GetPath() );
+      $new_archive->SetFilename( $this->path->GetFilename() );
       $this->archives[] = $new_archive;
     }
Index: /trunk/htdocs2/Classes/Pulsar/ObservationData2.php
===================================================================
--- /trunk/htdocs2/Classes/Pulsar/ObservationData2.php	(revision 407)
+++ /trunk/htdocs2/Classes/Pulsar/ObservationData2.php	(revision 407)
@@ -0,0 +1,194 @@
+<?php
+
+
+
+require_once 'Classes/Model/Observation.php';
+require_once 'Classes/Pulsar/CPSR2Combiner.php';
+
+
+
+class ObservationData2
+{
+  // PUBLIC
+
+  public function __construct( ObservationData2 $src = null )
+  {
+    if( $src != null )
+      $this->Copy( $src );
+    else
+    {
+      $this->observation_header = null;
+      $this->data_file = null;
+      $this->scrunched_file = null;
+      $this->scrunching_parameters = null;
+      $this->data_dir = null;
+    }
+  }
+  
+  public function Copy( ObservationData2 $src )
+  {
+    $this->observation_header = new Observation( $src->observation_header );
+    $this->data_file = new File( $src->data_file );
+    $this->scrunched_file = new File( $src->scrunched_file );
+    $this->scruncing_parameters = new ScrunchingParameters( $src->scrunching_parameters );
+  }
+  
+  public function GetOriginalFile() { return $this->priv_GetOriginalFile(); }
+  
+  public function GetDataFile() { return $this->priv_GetDataFile(); }
+
+  public function GetScrunchedFile() { return $this->priv_GetScrunchedFile(); }
+  
+  public function SetObservationHeader( Observation $s_observation_header ) { $this->observation_header = $s_observation_header; }
+  
+  public function SetScrunchingParameters( ScrunchingParameters $s_params ) { $this->scrunching_parameters = $s_params; }
+  
+  public function GetScrunchingParameters() { return $this->scrunching_parameters; }
+  
+  public function SetDataDir( Dir $s_data_dir ) { $this->data_dir = $s_data_dir; }
+  
+  public function EstimateDownloadableSize() { return $this->priv_EstimateDownloadableSize(); }
+  
+  public function MakeDownloadableFile() { return $this->priv_MakeDownloadableFile(); }
+  
+  // PRIVATE
+
+  private $observation_header;
+  private $data_file;
+  private $scrunched_file;
+  private $scrunching_parameters;
+  private $data_dir;
+  
+  private function priv_GetOriginalFile()
+  {
+    if( $this->observation_header == null )
+      throw new GZ_Exception( 'Observation header not set', 'ObservationData::priv_GetOriginalFile' );
+    
+    return $this->observation_header->GetFile();
+  }
+  
+  /**
+   * This function figures out the path to the datafile, if it doesn't exist it calls MakeDataFile
+   * to create it.
+   **/
+  private function priv_GetDataFile()
+  {
+    $original_file = $this->priv_GetOriginalFile();
+    
+    if( $this->data_dir == null )
+      throw new GZ_Exception( 'Data directory not set', 'ObservationData::priv_GetDataFile' );
+    
+    $this->data_file = File::ConvertFullPath( $this->data_dir->GetPath() . '/' . $original_file->GetFilename() );
+    
+    if( !$this->data_file->Exists() )
+      $this->MakeDataFile();
+    
+    return $this->data_file;
+  }
+  
+  /**
+   * Call GetDataFile so that we know the data file is created and have a File object pointing to it.
+   * If we have scrunching parameters and scrunching is required then perform the scrunching.
+   **/
+  public function priv_GetScrunchedFile()
+  {
+    if( $this->scrunching_parameters == null )
+      throw new GZ_Exception( 'Scrunching parameters not set', 'ObservationData2::priv_GetScrunchedFile' );
+    
+    if( !$this->scrunching_parameters->ScrunchingSet() )
+      throw new GZ_Exception( 'Scrunching parameters set but no scrunching required', 'ObservationData2::priv_GetScrunchedFile' );
+    
+    $original_file = $this->GetOriginalFile();
+    
+    $scr_filename = AddPreExtension( $original_file->GetFilename(), $this->scrunching_parameters->GetTextDescription() );
+    
+    $this->scrunched_file = File::ConvertFullPath( $this->data_dir->GetPath() . '/' . $scr_filename );
+    
+    if( !$this->scrunched_file->Exists() )
+      $this->MakeScrunchedFile();
+    
+    return $this->scrunched_file;
+  }
+  
+  public function priv_EstimateDownloadableSize()
+  {
+    $nbin = $this->observation_header->GetNBin();
+    $nchan = $this->observation_header->GetNChan();
+    $nsub = $this->observation_header->GetNSub();
+    $npol = $this->observation_header->GetNPol();
+    
+    $data_size = 2 * $nbin * $nchan * $nsub * $npol;
+    
+    if( $this->scrunching_parameters != null )
+    {
+      $scr_nchan = $this->scrunching_parameters->GetFScrunch();
+      $scr_nsub = $this->scrunching_parameters->GetTScrunch();
+      $scr_npol = $this->scrunching_parameters->GetPScrunch();
+      
+      $new_nchan = ceil( $nchan / $scr_nchan );
+      $new_nsub = ceil( $nsub / $scr_nsub );
+      $new_npol = $npol;
+      if( $scr_npol )
+        $new_npol = 1;
+      
+      $new_data_size = 2 * $nbin * $new_nchan * $new_nsub * $new_npol;
+      
+      $data_size = $new_data_size;
+    }
+    
+    return $data_size;
+  }
+  
+  /**
+   * If the original file is a directory, we psradd the archives in that directory together and put
+   * the result in a single file in the data directory. If the original file is a single file, we
+   * create a symlink to it from the data dir.
+   **/
+  private function MakeDataFile()
+  {
+    $original_file = $this->GetOriginalFile();
+    if( !$this->data_file->Exists() )
+    {
+      if( $original_file->IsDir() )
+      {
+        $src_dir = Dir::ConvertFile( $original_file );
+        $dir_contents = $src_dir->ListFiles();
+  
+        $combiner = new CPSR2Combiner();
+        foreach( $dir_contents as $next_file )
+        {
+          if( strpos( $next_file, '.cfb' ) !== false ||
+              strpos( $next_file, '.cf' ) !== false )
+          {
+            $combiner->AddArchive( File::ConvertFullPath( $src_dir->GetPath() . '/' . $next_file ) );
+          }
+        }
+        $combiner->SetDestFile( $this->data_file );
+        $combiner->Execute();
+      }
+      else
+        symlink( $original_file->GetFullPath(), $this->data_file->GetFullPath() );
+    }
+      
+  }
+  
+  //! Create the scrunched file from the data_file to the scrunched_file using the scrunching_parameters
+  private function MakeScrunchedFile()
+  {
+    $data_file = $this->priv_GetDataFile();
+    
+    $scruncher = new ArchiveScruncher();
+    $scruncher->SetSrcFile( $this->data_file );
+    $scruncher->SetDestFile( $this->scrunched_file );
+    $scruncher->SetParameters( $this->scrunching_parameters );
+    $scruncher->Execute();
+  }
+  
+  //! Make the data file, and then if needed make the scrunched file
+  private function priv_MakeDownloadableFile()
+  {
+    $this->GetDataFile();
+    if( $this->scrunching_parameters != null )
+      $this->MakeScrunchedFile();
+  }
+};
Index: /trunk/htdocs2/Classes/Tests/TestObservationData2.php
===================================================================
--- /trunk/htdocs2/Classes/Tests/TestObservationData2.php	(revision 407)
+++ /trunk/htdocs2/Classes/Tests/TestObservationData2.php	(revision 407)
@@ -0,0 +1,133 @@
+<?php
+
+
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Tests/BaseTest.php';
+require_once 'Classes/General/File.php';
+require_once 'Classes/Model/Observation.php';
+require_once 'Classes/Pulsar/ObservationData2.php';
+
+
+
+
+class TestObservationData2 extends BaseTest
+{
+  public function TestIt()
+  {
+    $this->TestCPSR2Data();
+    $this->TestDFBData();
+  }
+
+  /**
+   * Create a File pointing at the CPSR2 test dir
+   *
+   * Create an Observation object
+   * Set some test fields including filename,data_loc
+   *
+   * Create an ObservationData2 object
+   * set the observation
+   * Set the data directory
+   *
+   * Get the original file and check it
+   * Get the data file and check it
+   * Get the scrunched file and check it
+   **/
+  public function TestCPSR2Data()
+  {
+    $cpsr2_path = '/pulsar/archive05/CPSR2/J0437-4715/2006-04-11-05:10:39';
+    $data_path = '/pulsar/scratch01/data_archive';
+    $expected_data_file = File::ConvertFullPath( $data_path . '/' . '2006-04-11-05:10:39' );
+    $expected_scr_file = File::ConvertFullPath( $data_path .'/' . '2006-04-11-05:10:39_T1F128p' );
+
+    $cpsr2_file = File::ConvertFullPath( $cpsr2_path );
+    $data_dir = Dir::ConvertPathString( $data_path );
+    
+    $obs = new Observation();
+    $obs->SetFile( $cpsr2_file );
+    
+    $data = new ObservationData2();
+    $data->SetObservationHeader( $obs );
+    $data->SetDataDir( $data_dir );
+    
+    $scr_params = new ScrunchingParameters();
+    $scr_params->SetTScrunch( 1 );
+    $scr_params->SetFScrunch( 128 );
+    $scr_params->SetPScrunch();
+    
+    $data->SetScrunchingParameters( $scr_params );
+    
+    $original_file = $data->GetOriginalFile();
+    $data_file = $data->GetDataFile();
+    $scrunched_file = $data->GetScrunchedFile();
+    
+    $this->PerformTest( 'Testing GetOriginalFile',
+                        ( $original_file->GetFullPath() == $cpsr2_path ),
+                          'ObservationData2 returned the wrong path ' . $cspr2_path );
+    
+    $this->PerformTest( 'Testing GetDataFile',
+                         ( $expected_data_file->GetFullPath() == $data_file->GetFullPath() ),
+                           'Failed to create data file ' . $expected_data_file->GetFullPath() . ' ' . $data_file->GetFullPath() );
+    
+    $this->PerformTest( 'Testing GetScrunchedFile',
+                        ( $expected_scr_file->GetFullPath() == $scrunched_file->GetFullPath() ),
+                          'Failed to create scrunched file ' . $expected_scr_file->GetFullPath() . ' ' . $scrunched_file->GetFullPath() );
+  }
+
+  /**
+   * Create a File pointing at the DFB test dir
+   *
+   * Create an Observation object
+   * Set some test fields including filename,data_loc
+   *
+   * Create an ObservationData2 object
+   * set the observation
+   * Set the data directory
+   *
+   * Get the original file and check it
+   * Get the data file and check it
+   * Get the scrunched file and check it
+   **/
+  public function TestDFBData()
+  {
+    $src_archive = File::ConvertFullPath( '/pulsar/archive12/DFB/J1019-5749_R/r080208_114145.cf' );
+    $data_dir = Dir::ConvertPathString( '/pulsar/scratch01/data_archive' );
+    $expected_data_file = File::ConvertFullPath( '/pulsar/scratch01/data_archive/r080208_114145.cf' );
+    $expected_scr_file = File::ConvertFullPath( '/pulsar/scratch01/data_archive/r080208_114145_T1F128p.cf' );
+    
+    $obs = new Observation();
+    $obs->SetFile( $src_archive );
+    
+    $data = new ObservationData2();
+    $data->SetObservationHeader( $obs );
+    $data->SetDataDir( $data_dir );
+    
+    $scr_params = new ScrunchingParameters();
+    $scr_params->SetTScrunch( 1 );
+    $scr_params->SetFScrunch( 128 );
+    $scr_params->SetPScrunch();
+    
+    $data->SetScrunchingParameters( $scr_params );
+    
+    $original_file = $data->GetOriginalFile();
+    $data_file = $data->GetDataFile();
+    $scrunched_file = $data->GetScrunchedFile();
+    
+    $this->PerformTest( 'Testing GetOriginalFile',
+                        ( $original_file->GetFullPath() == $src_archive->GetFullPath() ),
+                          'ObservationData2 returned the wrong path ' . $original_file->GetFullPath() );
+    
+    $this->PerformTest( 'Testing GetDataFile',
+                        ( $expected_data_file->GetFullPath() == $data_file->GetFullPath() ),
+                          'Failed to create data file ' . $expected_data_file->GetFullPath() . ' ' . $data_file->GetFullPath() );
+    
+    $this->PerformTest( 'Testing GetScrunchedFile',
+                        ( $expected_scr_file->GetFullPath() == $scrunched_file->GetFullPath() ),
+                          'Failed to create scrunched file ' . $expected_scr_file->GetFullPath() . ' ' . $scrunched_file->GetFullPath() );
+  }
+};
+
+?>
+
