public SpeciesPropertiesViewModel(ScenarioSpecies species)
 {
     SpeciesDirectory = Path.GetDirectoryName(species.SpeciesDefinitionFilePath);
     LatinName = species.LatinName;
     PopulationDensity = species.PopulationDensity;
     SelectedSpecies = Path.GetFileNameWithoutExtension(species.SpeciesDefinitionFilename);
 }
        public static Animat Seed(ScenarioSpecies species, GeoRect geoRect, Bathymetry bathymetry)
        {
            var bounds = new GeoArray(geoRect.NorthWest, geoRect.NorthEast, geoRect.SouthEast, geoRect.SouthWest, geoRect.NorthWest);
            var result = new Animat { ScenarioSpecies = species };

            var area = bounds.Area;
            //Debug.WriteLine("Area: {0}",area);
            var population = (int)Math.Floor(area * species.PopulationDensity);
            for (var i = 0; i < population; i++)
            {
                var location = bounds.RandomLocationWithinPerimeter();
                var depth = bathymetry.Samples.GetNearestPoint(location).Data;
                if (depth < 0) result.Locations.Add(new Geo<float>(location.Latitude, location.Longitude, (float)(depth * Random.NextDouble())));
            }
            result.TotalAnimats = population;
            return result;
        }
 public static Animat Load(ScenarioSpecies species, string fileName)
 {
     var extension = Path.GetExtension(fileName);
     if (extension != null)
         switch (extension.ToLower())
         {
             case ".3mb":
                 return Animat3MBFile.Load(species, fileName);
             case ".ddb":
                 return AnimatDDBFile.Load(species, fileName);
             case ".ani":
                 return Load(fileName);
             default:
                 throw new FileFormatException(string.Format("Unable to load animat locations.  Unrecognized file type: \"{0}\"", extension));
         }
     throw new Exception("specified file does not exist!");
 }
 public async static Task<Animat> SeedAsyncWithout3MB(ScenarioSpecies species, GeoRect geoRect, Bathymetry bathymetry)
 {
     var bounds = new GeoArray(geoRect.NorthWest, geoRect.NorthEast, geoRect.SouthEast, geoRect.SouthWest, geoRect.NorthWest);
     var result = new Animat { ScenarioSpecies = species };
     
     var area = bounds.Area;
     //Debug.WriteLine("Area: {0}",area);
     var transformManyBlock = new TransformManyBlock<int, Geo<float>>(count =>
     {
         var geos = new List<Geo<float>>();
         for (var i = 0; i < count; i++)
         {
             var location = bounds.RandomLocationWithinPerimeter();
             var depth = bathymetry.Samples.GetNearestPointAsync(location).Result.Data;
             if (depth < -50) geos.Add(new Geo<float>(location.Latitude, location.Longitude, (float)(depth * Random.NextDouble())));
         }
         return geos;
     }, new ExecutionDataflowBlockOptions
     {
         TaskScheduler = TaskScheduler.Default,
         BoundedCapacity = -1,
         MaxDegreeOfParallelism = -1,
     });
     var bufferBlock = new BufferBlock<Geo<float>>();
     transformManyBlock.LinkTo(bufferBlock);
     var population = (int)Math.Round(area * species.PopulationDensity);
     result.TotalAnimats = population;
     const int blockSize = 100;
     while (population > 0)
     {
         transformManyBlock.Post(population > blockSize ? blockSize : population);
         population -= blockSize;
     }
     transformManyBlock.Complete();
     await transformManyBlock.Completion;
     IList<Geo<float>> animatGeos;
     if (bufferBlock.TryReceiveAll(out animatGeos))
         result.Locations.AddRange(animatGeos);
     return result;
 }
 void Copy(Scenario scenario)
 {
     Name = scenario.Name;
     Comments = scenario.Comments;
     ShowAllAnalysisPoints = scenario.ShowAllAnalysisPoints;
     ShowAllPerimeters = scenario.ShowAllPerimeters;
     ShowAllSpecies = scenario.ShowAllSpecies;
     StartTime = new TimeSpan(scenario.StartTime.Ticks);
     Duration = new TimeSpan(scenario.Duration.Ticks);
     TimePeriod = (TimePeriod)scenario.TimePeriod;
     Location = scenario.Location;
     Wind = scenario.Wind;
     SoundSpeed = scenario.SoundSpeed;
     Sediment = scenario.Sediment;
     Bathymetry = scenario.Bathymetry;
     // Here we map the old perimeter to the new perimeter so that the copied platform gets the proper perimeter
     var perimeterMap = new Dictionary<Guid, Guid>();
     foreach (var perimeter in scenario.Perimeters)
     {
         var newPerimeter = new Perimeter(perimeter) { Scenario = this };
         perimeterMap.Add(perimeter.Guid, newPerimeter.Guid);
         Perimeters.Add(newPerimeter);
     }
     var modeMap = new Dictionary<Guid, Guid>();
     var allModes = new List<Mode>();
     foreach (var platform in scenario.Platforms)
     {
         var newPlatform = new Platform(platform) { Scenario = this };
         // Make sure the new perimeter gets the proper copied perimeter from the original scenario
         if (platform.Perimeter != null) newPlatform.Perimeter = Perimeters.Find(p => p.Guid == perimeterMap[platform.Perimeter.Guid]);
         Platforms.Add(newPlatform);
         foreach (var source in platform.Sources)
         {
             var newSource = new Source(source) { Platform = newPlatform };
             newPlatform.Sources.Add(newSource);
             foreach (var mode in source.Modes)
             {
                 var newMode = new Mode(mode) { Source = newSource };
                 modeMap.Add(mode.Guid, newMode.Guid);
                 newSource.Modes.Add(newMode);
                 allModes.Add(newMode);
             }
         }
     }
     foreach (var analysisPoint in scenario.AnalysisPoints)
     {
         var newAnalysisPoint = new AnalysisPoint(analysisPoint) { Scenario = this };
         AnalysisPoints.Add(newAnalysisPoint);
         foreach (var transmissionLoss in analysisPoint.TransmissionLosses)
         {
             var newTransmissionLoss = new TransmissionLoss { AnalysisPoint = newAnalysisPoint, LayerSettings = new LayerSettings(transmissionLoss.LayerSettings) };
             foreach (var mode in transmissionLoss.Modes) 
                 newTransmissionLoss.Modes.Add(allModes.Find(m => m.Guid == modeMap[mode.Guid]));
             newAnalysisPoint.TransmissionLosses.Add(newTransmissionLoss);
             foreach (var radial in transmissionLoss.Radials)
             {
                 var newRadial = new Radial(radial) { TransmissionLoss = newTransmissionLoss };
                 newTransmissionLoss.Radials.Add(newRadial);
                 newRadial.CopyFiles(radial);
             }
         }
     }
     foreach (var species in scenario.ScenarioSpecies)
     {
         var newSpecies = new ScenarioSpecies(species) { Scenario = this };
         ScenarioSpecies.Add(newSpecies);
         newSpecies.CopyFiles(species);
     }
 }
        /// <summary>
        /// the header load procedure terminates once we have determined the species name, output configuration, and total number of animats -- it's all we need to display points on a map.
        /// </summary>
        /// <param name="species"> </param>
        /// <param name="fileName">the full path to the .3mb file</param>
        /// <returns></returns>
        public static new Animat3MBFile Load(ScenarioSpecies species, string fileName)
        {
            if (Path.GetExtension(fileName) != ".3mb") throw new FileFormatException("only 3MB files are supported.");
            var result = new Animat3MBFile();
            using (var reader = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read)))
            {
                #region MbFileIdentifier
                result.MbFileIdentifier = Encoding.Default.GetString(reader.ReadBytes(16)).TrimEnd('\0');
                if (result.MbFileIdentifier != "3MBBinaryOutput") throw new FileFormatException("Invalid 3MB file.");
                #endregion
                result.MbLibSuperVersion = reader.ReadUInt32();
                result.MbLibSubVersion = reader.ReadUInt32();
                result.MbSpeciesSuperVersion = reader.ReadUInt32();
                result.MbSpeciesSubVersion = reader.ReadUInt32();
                result.MbOutputSuperVersion = reader.ReadUInt32();
                result.MbOutputSubVersion = reader.ReadUInt32();
                #region NumberOfSpecies
                result.NumberOfSpecies = reader.ReadUInt32();
                if (result.NumberOfSpecies > 1) throw new FileFormatException(string.Format("The 3MB file {0} associated with this species contains more than one species!", Path.GetFileName(fileName)));
                #endregion
                result.TotalAnimats = reader.ReadInt32();
                result.Duration = reader.ReadUInt32();
                result.SavedStateCount = reader.ReadUInt32();
                result.StartClockTime = reader.ReadUInt32();
                result.OutputConfiguration = reader.ReadUInt32();
                result.SizeOfSizeT = reader.ReadInt32();
                result.MiscParams = reader.ReadUInt32();
                result.SeedValue = reader.ReadUInt32();
                result.AcousticSourceLimitsOutput = reader.ReadUInt32() != 0; //returns bool!
                result.NumAcousticSourceTypes = reader.ReadUInt32();
                result.NumAcousticSources = reader.ReadUInt32();
                result.IntervalLimitedFileOutputEnabled = reader.ReadUInt32() != 0;
                result.IntervalLimitedFileOutputStart = reader.ReadUInt32();
                result.IntervalLimitedFileOutputValue = reader.ReadUInt32();
                reader.BaseStream.Seek(28, SeekOrigin.Current);
                #region result.LatinName
                var buf = reader.ReadBytes(32);
                var end = false;
                for (var i = 0; i < buf.Length; i++)
                {
                    if (buf[i] == 0) end = true;
                    if (end) buf[i] = 0;
                }
                var latinName = Encoding.Default.GetString(buf).TrimEnd('\0');
                if (latinName != species.LatinName) throw new FileFormatException(string.Format("{0}: expected species name {1}, got {2}", fileName, species.LatinName, latinName));
                #endregion
                result.ActualPopulation = reader.ReadUInt32();
                result.InnerBoxDensity = reader.ReadSingle();
                result.OuterBoxDensity = reader.ReadSingle();
                result.TotalAnimatsOutsideTrack = reader.ReadUInt32();
                result.ActualAnimatsOutsideTrack = reader.ReadSingle();
                result.TotalAnimatsInsideTrack = reader.ReadUInt32();
                result.ActualAnimatsInsideTrack = reader.ReadSingle();
                reader.BaseStream.Seek(4, SeekOrigin.Current);
                reader.BaseStream.Seek(128, SeekOrigin.Current);
                result.ScenarioParams = reader.ReadUInt64();
                result.BathymetryMap = reader.ReadUInt64();
                result.SalinityMap = reader.ReadUInt64();
                result.TemperatureMap = reader.ReadUInt64();
                result.PostAnalysis = reader.ReadUInt64();
                result.SpeciesDescription = reader.ReadUInt64();
                result.AnimatToSpeciesAssociation = reader.ReadUInt64();
                result.AnimatsState = reader.ReadUInt64();
                result.AcousticExposure = reader.ReadUInt64();
                reader.BaseStream.Seek(8, SeekOrigin.Current);
                if (result.SizeOfSizeT != 4 && result.SizeOfSizeT != 8) throw new FileFormatException("Unknown architecture.");
                if (result.SizeOfSizeT == 4)
                {
                    result.ScenarioParamsSize = reader.ReadUInt32();
                    result.BathyMapSize = reader.ReadUInt32();
                    result.SalintyMapSize = reader.ReadUInt32();
                    result.TemperatureMapSize = reader.ReadUInt32();
                    result.PostAnalysisSize = reader.ReadUInt32();
                    result.SpeciesDescriptionSize = reader.ReadUInt32();
                    result.AnimatToSpeciesAssociationSize = reader.ReadUInt32();
                    result.AnimatStateSize = reader.ReadUInt32();
                    result.AcousticExposureSize = reader.ReadUInt32();
                    reader.BaseStream.Seek(12, SeekOrigin.Current);
                }
                if (result.SizeOfSizeT == 8)
                {
                    result.ScenarioParamsSize = reader.ReadUInt64();
                    result.BathyMapSize = reader.ReadUInt64();
                    result.SalintyMapSize = reader.ReadUInt64();
                    result.TemperatureMapSize = reader.ReadUInt64();
                    result.PostAnalysisSize = reader.ReadUInt64();
                    result.SpeciesDescriptionSize = reader.ReadUInt64();
                    result.AnimatToSpeciesAssociationSize = reader.ReadUInt64();
                    result.AnimatStateSize = reader.ReadUInt64();
                    result.AcousticExposureSize = reader.ReadUInt64();
                    reader.BaseStream.Seek(8, SeekOrigin.Current);
                }
                result.TotalBinaryFileOutputSize = reader.ReadUInt64();
                result.TotalAnimatBinaryFileOutputSize = reader.ReadUInt64();
                result.TotalAcousticExposureBinaryOutputSize = reader.ReadUInt64();
                reader.BaseStream.Seek(8, SeekOrigin.Current);

                result.ReadStartPositions(reader); //
            }
            return result;
        }
 public void Add(ScenarioSpecies species)
 {
     var existing = (from s in Context.ScenarioSpecies.Local
                     where s.LatinName == species.LatinName && s.Scenario == species.Scenario
                     select s).FirstOrDefault();
     if (existing != null) throw new DuplicateNameException(String.Format("A species named {0} already exists in scenario {1}, choose another name", species.LatinName, species.Scenario.Name));
     Log(species, "Added new species {0} to scenario {1} in location {2}", species.LatinName, species.Scenario.Name, species.Scenario.Location.Name);
 }
 void Log(ScenarioSpecies species, string message, params object[] args) { LogBase(new LogEntry(species) { Location = species.Scenario.Location, Scenario = species.Scenario, ScenarioSpecies = species }, message, args); }
        public async static Task<Animat> SeedAsync(ScenarioSpecies species, GeoRect geoRect, Bathymetry bathymetry)
        {
            var yxzFileName = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(Path.GetRandomFileName()) + ".txt");
            bathymetry.ToYXZ(yxzFileName, -1);
            var mbs = new C3mbs();
            mbsRESULT mbsResult;
            if (mbsRESULT.OK != (mbsResult = mbs.SetOutputDirectory(Path.GetTempPath())))
                throw new AnimatInterfaceMMBSException("SetOutputDirectory Error:" + mbs.ResultToTc(mbsResult));
            var config = mbs.GetConfiguration();
            config.enabled = false;             // binary output enabled/disabled
            config.durationLess = true;         // make sure we're in durationless mode.
            mbs.SetConfiguration(config);
            mbsResult = mbs.LoadBathymetryFromTextFile(yxzFileName);
            if (mbsRESULT.OK != mbsResult) throw new AnimatInterfaceMMBSException("Bathymetry failed to load: " + mbs.ResultToTc(mbsResult));
            mbsResult = mbs.AddSpecies(species.SpeciesDefinitionFilePath);
            if (mbsRESULT.OK != mbsResult) throw new AnimatInterfaceMMBSException(string.Format("C3mbs::AddSpecies FATAL error {0} for species {1}", mbs.ResultToTc(mbsResult), species.SpeciesDefinitionFilePath));

            var bounds = new GeoArray(geoRect.NorthWest, geoRect.NorthEast, geoRect.SouthEast, geoRect.SouthWest, geoRect.NorthWest);
            var result = new Animat { ScenarioSpecies = species };
            
            var area = bounds.Area;
            //Debug.WriteLine("Area: {0}",area);
            var transformManyBlock = new TransformManyBlock<int, Geo<float>>(count =>
            {
                var geos = new List<Geo<float>>();
                for (var i = 0; i < count; i++)
                {
                    var location = bounds.RandomLocationWithinPerimeter();
                    var depth = bathymetry.Samples.GetNearestPointAsync(location).Result.Data;
                    mbsRESULT retval;
                    lock (mbs) retval = mbs.AddIndividualAnimat(0, new mbsPosition { latitude = location.Latitude, longitude = location.Longitude, depth = 0 });
                    if (mbsRESULT.OK == retval) geos.Add(new Geo<float>(location.Latitude, location.Longitude, (float)(depth * Random.NextDouble())));
                }
                return geos;
            }, new ExecutionDataflowBlockOptions
            {
                TaskScheduler = TaskScheduler.Default,
                BoundedCapacity = -1,
                MaxDegreeOfParallelism = -1,
            });
            var bufferBlock = new BufferBlock<Geo<float>>();
            transformManyBlock.LinkTo(bufferBlock);
            var population = (int)Math.Round(area * species.PopulationDensity);
            result.TotalAnimats = population;
            const int blockSize = 100;
            while (population > 0)
            {
                transformManyBlock.Post(population > blockSize ? blockSize : population);
                population -= blockSize;
            }
            transformManyBlock.Complete();
            await transformManyBlock.Completion;
            //mbsResult = mbs.InitializeRun();
            //if (mbsRESULT.OK == mbsResult) while (mbsRUNSTATE.INITIALIZING == mbs.GetRunState()) Thread.Sleep(1);
            //else throw new AnimatInterfaceMMBSException("C3mbs::Initialize FATAL error " + mbs.ResultToTc(mbsResult));
            mbsResult = mbs.FinishRun();
            if (mbsRESULT.OK != mbsResult) throw new AnimatInterfaceMMBSException("C3mbs::FinishRun FATAL error " + mbs.ResultToTc(mbsResult));

            IList<Geo<float>> animatGeos;
            if (bufferBlock.TryReceiveAll(out animatGeos))
                result.Locations.AddRange(animatGeos);
            return result;
        }
 void SpeciesProperties(ScenarioSpecies species)
 {
     var vm = new SpeciesPropertiesViewModel(species) { WindowTitle = "Species Properties" };
     var result = Globals.VisualizerService.ShowDialog("SpeciesPropertiesView", vm);
     if ((result.HasValue) && (result.Value))
     {
         if (Math.Abs(vm.PopulationDensity - species.PopulationDensity) > 0.0001 || species.SpeciesDefinitionFilename != vm.SpeciesDefinitionFilename)
         {
             species.PopulationDensity = vm.PopulationDensity;
             species.SpeciesDefinitionFilename = vm.SpeciesDefinitionFilename;
             RepopulateSpeciesAsync(species);
         }
         if (vm.LatinName != species.LatinName) species.LatinName = vm.LatinName;
     }
 }
 static async Task RepopulateSpeciesAsync(ScenarioSpecies species)
 {
     species.RemoveMapLayers();
     species.Animat = await Animat.SeedAsync(species, species.Scenario.Location.GeoRect, species.Scenario.BathymetryData);
     species.Animat.Save(species.PopulationFilePath);
     species.UpdateMapLayers();
 }
 void RepopulateSpecies(ScenarioSpecies species)
 {
     RepopulateSpeciesAsync(species);
     OnPropertyChanged("IsSaveScenarioCommandEnabled");
 }
 void DeleteSpecies(ScenarioSpecies species)
 {
     if (Globals.MessageBoxService.ShowYesNo(string.Format("Are you sure you want to delete the species \"{0}\"?", species.LatinName), MessageBoxImage.Warning) != MessageBoxResult.Yes) return;
     species.Delete();
     OnPropertyChanged("IsRunSimulationCommandEnabled");
     OnPropertyChanged("IsSaveScenarioCommandEnabled");
 }
        async void AddSpecies(Scenario scenario)
        {
            var vm = new SpeciesPropertiesViewModel(new ScenarioSpecies
            {
                LatinName = "Generic odontocete", 
                PopulationDensity = 0.01f, 
                SpeciesDefinitionFilename = "Generic odontocete.spe"
            })
            {
                WindowTitle = "Add new species"
            };
            var result = Globals.VisualizerService.ShowDialog("SpeciesPropertiesView", vm);
            if ((!result.HasValue) || (!result.Value)) return;
            var species = new ScenarioSpecies
            {
                Scenario = scenario,
                LatinName = vm.LatinName,
                PopulationDensity = vm.PopulationDensity,
                SpeciesDefinitionFilename = vm.SpeciesDefinitionFilename,
            };

            try
            {
                scenario.ScenarioSpecies.Add(species);
                species.LayerSettings.LineOrSymbolSize = 3;
                var animats = await Animat.SeedAsync(species, scenario.Location.GeoRect, scenario.BathymetryData);
                animats.Save(species.PopulationFilePath);
                species.UpdateMapLayers();
            }
            catch (Exception e)
            {
                scenario.ScenarioSpecies.Remove(species);
                Globals.MessageBoxService.ShowError(e.Message);
            }
            OnPropertyChanged("IsRunSimulationCommandEnabled");
            OnPropertyChanged("IsSaveScenarioCommandEnabled");
        }
        /// <summary>
        /// the header load procedure terminates once we have determined the species name, output configuration, and total number of animats -- it's all we need to display points on a map.
        /// </summary>
        /// <param name="species"> </param>
        /// <param name="fileName">the full path to the .ddb file</param>
        /// <returns></returns>
        public new static AnimatDDBFile Load(ScenarioSpecies species, string fileName)
        {
            if (Path.GetExtension(fileName) != ".ddb") throw new FileFormatException("only ddb files are supported.");
            var result = new AnimatDDBFile();
            using (var reader = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read)))
            {
                //nuwc tests for header if 3mb here. (16 byte check)
                result.MbLibSuperVersion = reader.ReadInt32();
                result.MbLibSubVersion = reader.ReadInt32();

                if (result.MbLibSuperVersion > 4)
                {
                    result.MbSbSuperVersion = reader.ReadInt32();
                    result.MbSbSubVersion = reader.ReadInt32();
                    result.MbOutSuperVersion = reader.ReadInt32();
                    result.MbOutSubVersion = reader.ReadInt32();
                }
                else
                {
                    result.MbSbSuperVersion = 0;
                    result.MbSbSubVersion = 0;
                    result.MbOutSuperVersion = 0;
                    result.MbOutSubVersion = 0;
                }

                result.MbNumSpecies = reader.ReadInt32();
                result.TotalAnimats = reader.ReadInt32();
                result.MbIterationCount = reader.ReadInt32();
                result.MbSavedStateCount = reader.ReadInt32();
                result.MbStartClockTime = reader.ReadInt32();
                result.MbOutputConfiguration = reader.ReadInt32();
                result.MbSizeData = reader.ReadInt32();

                if (result.MbLibSuperVersion > 4)
                {
                    result.MbSpeciesGroup = 0;
                    result.MbMscParams = reader.ReadInt32();
                    result.MbSeedValue = reader.ReadInt32();
                    result.MbAcsticSourceLimitsOutput = reader.ReadInt32();
                    result.MbNumAcsticSrcTypes = reader.ReadInt32();
                    result.MbNumAcsticSrcs = reader.ReadInt32();
                }
                else
                {
                    result.MbSpeciesGroup = reader.ReadInt32();
                    result.MbMscParams = 0;
                    result.MbSeedValue = 0;
                    result.MbAcsticSourceLimitsOutput = 0;
                    result.MbNumAcsticSrcTypes = 0;
                    result.MbNumAcsticSrcs = 0;
                }

                // case for special .smb readers with pop and species name
                // logger.trace("Checking for super version 4 and subversion greater than 200");

                if (result.MbLibSuperVersion == 4 && result.MbLibSubVersion > 200)
                {
                    //logger.trace("version > 4.200 ( real value: " + getVersionString() + ")");

                    //  this.population = reader.ReadInt32();
                    result.ActualMammalPopulation = reader.ReadInt32();
                    var latinName = Encoding.ASCII.GetString(reader.ReadBytes(32)).TrimEnd('\0').Trim();
                    if (latinName != species.LatinName) throw new FileFormatException(string.Format("{0}: expected species name {1}, got {2}", fileName, species.LatinName, latinName));
                    //result.LatinName = reader.ReadString().TrimEnd('\0').Trim();

                    //  this.speciesName = new String(specName).trim();

                    // SpeciesEntry e = SpeciesTable.lookupEntryByScientific(speciesName);

                    //   if (e != null)
                    //  {
                    //       this.speciesCode = e.getKey();
                    //    }
                    //  else
                    //{
                    //    logger.warn("species table lookup failed: " + speciesName);
                    //}
                }
                else
                {
                    //          logger.trace("version <= 4.200. actual " + getVersionString() + ". no spec name or pop");

                    //if we can't get the population and name, it's not a valid .ddb file.  Choke and die.
                    throw new System.IO.FileFormatException("");
                }

#if false

    // Internal File Pointers To Various Regions

                result.MbScenarioParams = reader.ReadInt64();
                result.MbBathymetryMap = reader.ReadInt64();
                result.MbSalinityMap = reader.ReadInt64();
                result.MbTemperatureMap = reader.ReadInt64();
                result.MbPostAnalisys = reader.ReadInt64();
                result.MbSpeciesDescription = reader.ReadInt64();
                result.MbAnimatToSpeciesAssociation = reader.ReadInt64();
                result.MbAnimatsState = reader.ReadInt64();
                result.MbAcousticExposure = reader.ReadInt64();
                try
                {
                    reader.ReadBytes(8);
                }
                catch
                {
                    throw new System.IO.FileFormatException("");
                }

                // Storage Bytes of Each Region

                // this is in case the file was written by a 64 bit system.  4 = 32
                // bit, 8 = 64 bit.
                if (result.MbSizeData == 4)
                {
                    result.MbScenarioParamsSize = reader.ReadInt32();
                    result.MbBathyMapSize = reader.ReadInt32();
                    result.MbSalinityMapSize = reader.ReadInt32();
                    result.MbTemperatureMapSize = reader.ReadInt32();
                    result.MbPostAnalisysSize = reader.ReadInt32();
                    result.MbSpeciesDescriptionSize = reader.ReadInt32();
                    result.MbAnimatSpeciesAssSize = reader.ReadInt32();
                    result.MbAnimatStateSize = reader.ReadInt32();
                    result.MbAcousticExposureSize = reader.ReadInt32();
                    byte[] bytes = reader.ReadBytes(12);
                    if (bytes.Length != 12) throw new ApplicationException("loadFromFile: skip 12 failed");
                }
                else
                {
                    result.MbScenarioParamsSize = reader.ReadInt64();
                    result.MbBathyMapSize = reader.ReadInt64();
                    result.MbSalinityMapSize = reader.ReadInt64();
                    result.MbTemperatureMapSize = reader.ReadInt64();
                    result.MbPostAnalisysSize = reader.ReadInt64();
                    result.MbSpeciesDescriptionSize = reader.ReadInt64();
                    result.MbAnimatSpeciesAssSize = reader.ReadInt64();
                    result.MbAnimatStateSize = reader.ReadInt64();
                    result.MbAcousticExposureSize = reader.ReadInt64();

                    try
                    {
                        reader.ReadBytes(8);
                    }
                    catch
                    {
                        throw new System.IO.FileFormatException("");
                    }
                }
                if (result.MbLibSuperVersion == 4 && result.MbLibSubVersion > 300)
                {
                    try
                    {
                        reader.ReadBytes(16);
                    }
                    catch
                    {
                        throw new System.IO.FileFormatException("");
                    }

                    result.SimAreaTotal = reader.ReadInt32();
                    result.SimAreaPopulation = reader.ReadSingle();
                    result.TrackAreaTotal = reader.ReadInt32();
                    result.TrackAreaPopulation = reader.ReadSingle();

                    this.population = (int)(result.SimAreaPopulation + result.TrackAreaPopulation);
                    this.totalAnimats = result.SimAreaTotal + result.TrackAreaTotal;

             //       logger.trace("total population overridden by inbox / outbox based on file version");
                }
                else
                {
                    try
                    {
                        reader.ReadBytes(32);
                    }
                    catch
                    {
                        throw new System.IO.FileFormatException("");
                    }
                    // Species Groups.  form a list for viewing.

                    groupList.clear();

                    var speGroupName = new byte[32];

                    for (int i = 0; i < 8; i++)
                    {
                        var name = reader.ReadBytes(32).ToString();

                        float lvlAphys = reader.ReadSingle();
                        float lvlBphys = reader.ReadSingle();
                        float lvlBBeh = reader.ReadSingle();

                        try
                        {
                            reader.ReadBytes(36);
                        }
                        catch
                        {
                            throw new System.IO.FileFormatException("");
                        }

                        if (speGroupName[0] > 0)
                        {
                            var builder = new StringBuilder();
                            builder.Append(speGroupName.ToString().Trim());
                            builder.Append(", ");
                            builder.Append(lvlAphys);
                            builder.Append(", ");
                            builder.Append(lvlBphys);
                            builder.Append(", ");
                            builder.Append(lvlBBeh);

                            groupList.add(builder.ToString());


                        }
                    }

                    // update for population
                    if (population == 0)
                    {
                        population = MbTotalAnimats;
                    }

                    // if we made it here, the definition is valid

                    result.SpeciesFilePath = fileName;

                //logger.info("Loaded " + this.speciesName + ", file version " + getVersionString() + ", with " +
                //            MbIterationCount + " iteration step");
#endif

                result.ReadStartPositions(reader); //
            }
            return result;
        }

        /// <summary>
        /// jumps the .ddb header, and then populates AnimatStartPoints with the starting locations of every animat in the file.
        /// </summary>
        /// <param name="reader"></param>
        void ReadStartPositions(BinaryReader reader)
        {
            reader.BaseStream.Seek(1040, SeekOrigin.Begin); // skip the .ddb header
            Locations = new AnimatEnvironmentData<Geo<float>>();
            var datasize = GetSize(MbOutputConfiguration);
            for (var i = 0; i < TotalAnimats; i++)
            {
                //var id = reader.ReadSingle();
                //var time = reader.ReadSingle();
                reader.BaseStream.Seek(8, SeekOrigin.Current); //skip id and time
                var lat = reader.ReadSingle();
                var lon = reader.ReadSingle();
                //AnimatStartPoints.Add(new Geo(reader.ReadSingle(), reader.ReadSingle()));
                //adds lat and lon.
                //reader.BaseStream.Seek(8 + datasize, SeekOrigin.Current);

                var depth = reader.ReadSingle();
                Locations.Add(new Geo<float>(lat, lon, depth));
                reader.BaseStream.Seek(4 + datasize, SeekOrigin.Current);
                // skip packedData, and the data itself.
                //var packedData = reader.ReadSingle();
                //reader.BaseStream.Seek(datasize, SeekOrigin.Current);

                // reader.BaseStream.Seek(GetSize(MbOutputConfiguration), SeekOrigin.Current);
                //skip its data because we don't care.
            }
        }