mirror of
https://github.com/JHUAPL/JCAT.git
synced 2026-01-08 23:47:59 -05:00
Initial commit
This commit is contained in:
7
LICENSE.md
Normal file
7
LICENSE.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Copyright 2024, The Johns Hopkins University Applied Physics Laboratory
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
31
README.md
Normal file
31
README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# JCAT
|
||||
|
||||
Java CRISM Analysis Tool
|
||||
|
||||
JCAT is a free analysis tool for Compact Reconnaissance Imaging Spectrometer for Mars (CRISM) data products. It is released under the MIT license.
|
||||
|
||||
## Installation
|
||||
Clone this repository from the command line:
|
||||
```
|
||||
> git clone git@github.com:JHUAPL/JCAT.git
|
||||
```
|
||||
In the cloned folder ('jcat'), run the mkPackage.bash script:
|
||||
```
|
||||
> ./mkPackage.bash
|
||||
```
|
||||
This script will create two tar files in the 'dist' directory. Expand that tar file either in a finder window or via command line:
|
||||
```
|
||||
> tar -xvzf ./dist/JCAT-XXXX.XX.XX.tar.gz
|
||||
```
|
||||
Open runJCAT in your corresponding OS via finder window or command line to start using JCAT:
|
||||
```
|
||||
> ./JCAT-XXXX.XX.XX/unix/runJCAT
|
||||
```
|
||||
|
||||
## Tutorial / Documentation
|
||||
|
||||
There is a tutorial PDF available when running JCAT. Under the _Help_ tab, click on the _Tutorial_ button to open the document.
|
||||
|
||||
The _Show Log_ button is useful for debugging.
|
||||
|
||||
|
||||
33
doc/index.html
Normal file
33
doc/index.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>The Java CRISM Analysis Tool (JCAT)</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>
|
||||
The Java CRISM Analysis Tool (JCAT) can be used to view CRISM data
|
||||
downloaded from the Planetary Data System
|
||||
(PDS) <a href="https://pds-geosciences.wustl.edu/">Geosciences Node</a>
|
||||
at <a href="https://wustl.edu/">Washington University</a> in
|
||||
St. Louis.
|
||||
<p>
|
||||
JCAT requires Java version 8 or later to run, along with Java FX.
|
||||
The <a href="https://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html">Java
|
||||
SE Runtime Environment 8</a> (JRE) from Oracle includes both.
|
||||
<p>
|
||||
JCAT is distributed as a jar file. Version 1.0 was released on Nov
|
||||
1, 2019. Double click the jar file, or from the command line, type
|
||||
<pre>
|
||||
java -jar JCAT.jar
|
||||
</pre>
|
||||
<p>
|
||||
Follow the <a href="JCAT_Tutorial.pdf">JCAT Tutorial</a> to get
|
||||
started.
|
||||
|
||||
<p>
|
||||
Contact <a href="mailto:Hari.Nair@jhuapl.edu">Hari Nair</a> for help,
|
||||
bug reports, or suggestions.
|
||||
</p>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
137
mkPackage.bash
Executable file
137
mkPackage.bash
Executable file
@@ -0,0 +1,137 @@
|
||||
#!/bin/bash
|
||||
|
||||
function build_jar() {
|
||||
cwd=$(pwd)
|
||||
cd $(dirname $0)
|
||||
|
||||
date=$(date +"%Y-%b-%d %H:%M:%S %Z")
|
||||
|
||||
if [ -d .git ]; then
|
||||
rev=$(git rev-parse --verify --short HEAD)
|
||||
else
|
||||
rev="UNVERSIONED"
|
||||
fi
|
||||
|
||||
mvn clean install
|
||||
|
||||
if [ ! -f target/${package}.jar ]; then
|
||||
echo "compilation failed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cd $cwd
|
||||
}
|
||||
|
||||
function make_scripts() {
|
||||
cwd=$(pwd)
|
||||
|
||||
binDir=${root}/unix
|
||||
batchDir=${root}/windows
|
||||
libDir=${root}/lib
|
||||
|
||||
mkdir -p ${binDir}
|
||||
mkdir -p ${batchDir}
|
||||
mkdir -p ${libDir}
|
||||
rsync -a target/${package}.jar ${libDir}
|
||||
rsync -a target/${package}_lib ${libDir}
|
||||
|
||||
for class in $(jar tf target/${package}.jar | grep $appSrcDir | grep -v '\$' | grep class); do
|
||||
base=$(basename $class ".class")
|
||||
tool=${binDir}/${base}
|
||||
path=$(dirname $class | sed 's,/,.,g').${base}
|
||||
echo "#!/bin/bash" > ${tool}
|
||||
echo 'root=$(dirname $0)' >> ${tool}
|
||||
echo 'MEMSIZE=""' >> ${tool}
|
||||
echo 'if [ "$(uname)" == "Darwin" ]; then' >> ${tool}
|
||||
echo ' MEMSIZE=$(sysctl hw.memsize | awk '\''{print int($2/1024)}'\'')' >> ${tool}
|
||||
echo 'elif [ "$(uname)" == "Linux" ]; then' >> ${tool}
|
||||
echo ' MEMSIZE=$(grep MemTotal /proc/meminfo | awk '\''{print $2}'\'')' >> ${tool}
|
||||
echo 'fi' >> ${tool}
|
||||
echo 'java=$(which java)' >> ${tool}
|
||||
echo 'if [ -z $java ]; then' >> ${tool}
|
||||
echo ' echo "Java executable not found in your PATH"' >> ${tool}
|
||||
echo ' exit 1' >> ${tool}
|
||||
echo 'fi' >> ${tool}
|
||||
echo 'fullVersion=$(java -version 2>&1 | head -1 |awk -F\" '\''{print $2}'\'')' >> ${tool}
|
||||
echo 'version=$(echo $fullVersion | awk -F\. '\''{print $1}'\'')' >> ${tool}
|
||||
echo 'if [ "$version" -lt "17" ];then' >> ${tool}
|
||||
echo ' echo "minimum Java version required is 17. Version found is $fullVersion."' >> ${tool}
|
||||
echo ' exit 1' >> ${tool}
|
||||
echo 'fi' >> ${tool}
|
||||
echo "java -Xmx\${MEMSIZE}K -cp \${root}/../lib/*:\${root}/../lib/${package}_lib/* $path \$@" >> ${tool}
|
||||
|
||||
chmod +x ${tool}
|
||||
|
||||
tool=${batchDir}/${base}.bat
|
||||
echo '@ECHO OFF' > ${tool}
|
||||
echo 'set root=%~dp0\..' >> ${tool}
|
||||
echo 'set CLASSPATH=%root%\lib\JCAT.jar;%root%\lib\JCAT_lib\*' >> ${tool}
|
||||
echo '' >> ${tool}
|
||||
echo ':: https://stackoverflow.com/questions/11343190/how-to-check-available-memory-ram-via-batch-script' >> ${tool}
|
||||
echo 'for /f "skip=1" %%p in ('\''wmic os get freephysicalmemory'\'') do ( ' >> ${tool}
|
||||
echo ' set memsize=%%p' >> ${tool}
|
||||
echo ' goto :done' >> ${tool}
|
||||
echo ')' >> ${tool}
|
||||
echo ':done' >> ${tool}
|
||||
echo '' >> ${tool}
|
||||
echo ':: https://stackoverflow.com/questions/17714681/get-java-version-from-batch-file' >> ${tool}
|
||||
echo 'for /f tokens^=2-5^ delims^=.-_^" %%j in ('\''java -fullversion 2^>^&1'\'') do set "version=%%j"' >> ${tool}
|
||||
echo '' >> ${tool}
|
||||
echo 'if %version% LSS 17 (' >> ${tool}
|
||||
echo 'ECHO minimum Java version required is 17. Version found is %version%.' >> ${tool}
|
||||
echo ') else (' >> ${tool}
|
||||
echo 'java -Xmx%memsize%K app.runJCAT' >> ${tool}
|
||||
echo ')' >> ${tool}
|
||||
echo ':: Keep the CMD window open in case of errors' >> ${tool}
|
||||
echo 'PAUSE' >> ${tool}
|
||||
|
||||
done
|
||||
cd $cwd
|
||||
}
|
||||
|
||||
### Don't need to modify anything below this line
|
||||
|
||||
package=JCAT
|
||||
root=${package}-$(date "+%Y.%m.%d")
|
||||
|
||||
java=$(which java)
|
||||
if [ -z $java ]; then
|
||||
echo "Java executable not found in your PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cwd=$(pwd)
|
||||
cd $(dirname $0)
|
||||
|
||||
srcFile="./src/main/java/util/AppVersion.java"
|
||||
appSrcDir='app'
|
||||
|
||||
java=$(which java)
|
||||
if [ -z $java ]; then
|
||||
echo "Java executable not found in your PATH"
|
||||
exit 1
|
||||
fi
|
||||
fullVersion=$(java -version 2>&1 | head -1 |awk -F\" '{print $2}')
|
||||
version=$(echo $fullVersion | awk -F\. '{print $1}')
|
||||
if [ "$version" -lt "17" ];then
|
||||
echo "minimum Java version required is 17. Version found is $fullVersion."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
build_jar
|
||||
make_scripts
|
||||
|
||||
if [ -d .git ]; then
|
||||
git restore $srcFile
|
||||
fi
|
||||
|
||||
cd $cwd
|
||||
|
||||
mkdir -p dist
|
||||
tar cfz ./dist/${root}.tar.gz ./${root}
|
||||
rsync -a mkPackage.bash pom.xml src ${root}-src/
|
||||
tar cfz ./dist/${root}-src.tar.gz ./${root}-src
|
||||
|
||||
echo -e "\nCreated ./dist/${root}.tar.gz ./dist/${root}-src.tar.gz"
|
||||
|
||||
/bin/rm -fr ${root} ./${root}-src
|
||||
244
pom.xml
Normal file
244
pom.xml
Normal file
@@ -0,0 +1,244 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>jcat</groupId>
|
||||
<artifactId>jcat</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>JCAT</name>
|
||||
<description>Java CRISM Analysis Tool</description>
|
||||
<organization>
|
||||
<name>Johns Hopkins University Applied Physics Lab</name>
|
||||
<url>https://www.jhuapl.edu</url>
|
||||
</organization>
|
||||
|
||||
<properties>
|
||||
<package>JCAT</package>
|
||||
|
||||
<mainClass>app.runJCAT</mainClass>
|
||||
|
||||
<!-- Sets proper encoding -->
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8
|
||||
</project.reporting.outputEncoding>
|
||||
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<javafx.version>17</javafx.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<release>17</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!--This plugin's configuration is used to store Eclipse m2e settings
|
||||
only. It has no influence on the Maven build itself. See https://stackoverflow.com/questions/9142533/plugin-execution-not-covered-by-lifecycle-configuration-jbossas-7-ear-archetype -->
|
||||
<plugin>
|
||||
<groupId>org.eclipse.m2e</groupId>
|
||||
<artifactId>lifecycle-mapping</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<configuration>
|
||||
<lifecycleMappingMetadata>
|
||||
<pluginExecutions>
|
||||
<pluginExecution>
|
||||
<pluginExecutionFilter>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<versionRange>[3.0.0,)</versionRange>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
</pluginExecutionFilter>
|
||||
<action>
|
||||
<ignore />
|
||||
</action>
|
||||
</pluginExecution>
|
||||
</pluginExecutions>
|
||||
</lifecycleMappingMetadata>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
||||
<!-- The following dependencies are needed to create the complete package -->
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${basedir}/target/${package}</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-dependencies</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/${package}_lib
|
||||
</outputDirectory>
|
||||
<overWriteReleases>false</overWriteReleases>
|
||||
<overWriteSnapshots>false</overWriteSnapshots>
|
||||
<overWriteIfNewer>true</overWriteIfNewer>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>lib/</classpathPrefix>
|
||||
<mainClass>${mainClass}</mainClass>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Class-Path>.</Class-Path>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
|
||||
<finalName>${package}</finalName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<id>createVersionFile</id>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>${project.basedir}/src/main/bash/createVersionFile.bash</executable>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>1.9.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-configuration2</artifactId>
|
||||
<version>2.7</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-csv</artifactId>
|
||||
<version>1.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.8.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>3.6.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
</dependency>
|
||||
|
||||
<!-- javafx dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-swing</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- adding all the platform libs only adds a couple more MB -->
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<classifier>win</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<classifier>mac</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<classifier>linux</classifier>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
37
src/main/bash/createVersionFile.bash
Executable file
37
src/main/bash/createVersionFile.bash
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script is run from maven. See the exec-maven-plugin block in the pom.xml file.
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
date=$(date -u +"%Y-%b-%d %H:%M:%S %Z")
|
||||
|
||||
rev=$(git rev-parse --verify --short HEAD)
|
||||
if [ $? -gt 0 ]; then
|
||||
rev="UNVERSIONED"
|
||||
fi
|
||||
|
||||
srcFile=../src/main/java/util/AppVersion.java
|
||||
mkdir -p $(dirname $srcFile)
|
||||
|
||||
touch $srcFile
|
||||
|
||||
cat <<EOF > $srcFile
|
||||
|
||||
package util;
|
||||
|
||||
public class AppVersion {
|
||||
private static String gitRevision = new String("$rev");
|
||||
private static String applicationName = new String("JCAT");
|
||||
private static String dateString = new String("$date");
|
||||
|
||||
private AppVersion() {}
|
||||
|
||||
/**
|
||||
* version $rev (built $date)
|
||||
*/
|
||||
public static String getVersionString() {
|
||||
return String.format("%s version %s (built %s)", applicationName, gitRevision, dateString);
|
||||
}
|
||||
}
|
||||
EOF
|
||||
11
src/main/java/app/runJCAT.java
Normal file
11
src/main/java/app/runJCAT.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package app;
|
||||
|
||||
import javafx.buildGUI;
|
||||
|
||||
public class runJCAT {
|
||||
|
||||
public static void main(String[] args) {
|
||||
buildGUI.main(args);
|
||||
}
|
||||
|
||||
}
|
||||
231
src/main/java/definition/PDS/BlockFile.java
Normal file
231
src/main/java/definition/PDS/BlockFile.java
Normal file
@@ -0,0 +1,231 @@
|
||||
package definition.PDS;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import util.JCATLog;
|
||||
|
||||
public class BlockFile {
|
||||
protected RandomAccessFile fileDataInput = null;
|
||||
protected String fullPath = null;
|
||||
protected int blockSize = PDSImage.typicalPageSize;
|
||||
protected byte block[] = null;
|
||||
protected int blockOffset = 0;
|
||||
protected int fileSize = 0;
|
||||
|
||||
public BlockFile(String filename) throws IOException {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating BlockFile object");
|
||||
|
||||
fullPath = filename;
|
||||
|
||||
openFile(filename);
|
||||
}
|
||||
|
||||
public BlockFile(String filename, int bufferSize) throws IOException {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating BlockFile object");
|
||||
fullPath = filename;
|
||||
blockSize = bufferSize;
|
||||
|
||||
openFile(filename, bufferSize);
|
||||
}
|
||||
|
||||
public void openFile(String filename) throws IOException {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method openFile 1 parameter");
|
||||
fullPath = filename;
|
||||
readBlock(0, blockSize);
|
||||
|
||||
if (fileDataInput == null) {
|
||||
fileDataInput = new RandomAccessFile(filename, "r");
|
||||
fileSize = (int) fileDataInput.length();
|
||||
blockSize = fileSize / 100;
|
||||
fullPath = filename;
|
||||
readBlock(0, blockSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void openFile(String filename, int bufferSize) throws IOException {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method openFile 2 parameter");
|
||||
fullPath = filename;
|
||||
blockSize = bufferSize;
|
||||
|
||||
readBlock(0, blockSize);
|
||||
|
||||
|
||||
if (fileDataInput == null) {
|
||||
|
||||
fileDataInput = new RandomAccessFile(filename, "r");
|
||||
fileSize = (int) fileDataInput.length();
|
||||
blockSize = bufferSize;
|
||||
fullPath = filename;
|
||||
readBlock(0, blockSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void openFile() throws IOException {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method openFile 0 paramter");
|
||||
openFile(fullPath);
|
||||
}
|
||||
|
||||
public void closeFile() throws IOException {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method closeFile");
|
||||
if (isOpen()) {
|
||||
fileDataInput.close();
|
||||
fileDataInput = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getFullPath() {
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return (block != null);
|
||||
}
|
||||
|
||||
public byte readByte(int offset) throws IOException {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method readByte");
|
||||
byte result = 0;
|
||||
|
||||
readBlock(offset, 1);
|
||||
result = block[offset - blockOffset];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public short readShort(int offset) throws IOException {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method readShort");
|
||||
short result = 0;
|
||||
|
||||
readBlock(offset, 2);
|
||||
int v = ((block[offset - blockOffset] & 0xff) << 8) | (block[offset - blockOffset + 1] & 0xff);
|
||||
result = (short) v;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public float readFloat(int offset) throws IOException {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method readFloat");
|
||||
float result = 0;
|
||||
|
||||
readBlock(offset, 4);
|
||||
|
||||
if (block != null)
|
||||
result = Float.intBitsToFloat(
|
||||
(block[offset - blockOffset + 3] & 0xff) | ((block[offset - blockOffset + 2] & 0xff) << 8)
|
||||
| ((block[offset - blockOffset + 1] & 0xff) << 16)
|
||||
| ((block[offset - blockOffset] & 0xff) << 24));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public float readPCFloat(int offset) throws IOException {
|
||||
|
||||
float result = 0;
|
||||
|
||||
readBlock(offset, 4);
|
||||
|
||||
if (block != null)
|
||||
result = Float.intBitsToFloat(
|
||||
(block[offset - blockOffset] & 0xff) | ((block[offset - blockOffset + 1] & 0xff) << 8)
|
||||
| ((block[offset - blockOffset + 2] & 0xff) << 16)
|
||||
| ((block[offset - blockOffset + 3] & 0xff) << 24));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public int readInt(int offset) throws IOException {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method readInt");
|
||||
int result = 0;
|
||||
|
||||
readBlock(offset, 4);
|
||||
|
||||
if (block != null) {
|
||||
int byte1 = block[offset - blockOffset];
|
||||
int byte2 = block[offset - blockOffset + 1];
|
||||
int byte3 = block[offset - blockOffset + 2];
|
||||
int byte4 = block[offset - blockOffset + 3];
|
||||
|
||||
result =
|
||||
(byte4 & 0xff) | ((byte3 & 0xff) << 8) | ((byte2 & 0xff) << 16) | ((byte1 & 0xff) << 24);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public double readDouble(int offset) throws IOException {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method readDouble");
|
||||
double result = 0;
|
||||
|
||||
readBlock(offset, 8);
|
||||
|
||||
if (block != null) {
|
||||
long byte1 = block[offset - blockOffset];
|
||||
long byte2 = block[offset - blockOffset + 1];
|
||||
long byte3 = block[offset - blockOffset + 2];
|
||||
long byte4 = block[offset - blockOffset + 3];
|
||||
long byte5 = block[offset - blockOffset + 4];
|
||||
long byte6 = block[offset - blockOffset + 5];
|
||||
long byte7 = block[offset - blockOffset + 6];
|
||||
long byte8 = block[offset - blockOffset + 7];
|
||||
|
||||
long bits = (byte8 & 0xff) | ((byte7 & 0xff) << 8) | ((byte6 & 0xff) << 16)
|
||||
| ((byte5 & 0xff) << 24) | ((byte4 & 0xff) << 32) | ((byte3 & 0xff) << 40)
|
||||
| ((byte2 & 0xff) << 48) | ((byte1 & 0xff) << 56);
|
||||
|
||||
result = Double.longBitsToDouble(bits);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void readBlock(int offset, int length) throws IOException {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method readBlock");
|
||||
if (blockSize <= 0)
|
||||
blockSize = PDSImage.typicalPageSize;
|
||||
|
||||
if ((block == null) || (offset > (blockOffset + blockSize)) || (offset < blockOffset)
|
||||
|| ((offset + length) > (blockOffset + blockSize))) {
|
||||
// RandomAccessFile fileDataInput = new
|
||||
// RandomAccessFile(filename, "r");
|
||||
if (fullPath == null)
|
||||
return;
|
||||
|
||||
if (fileDataInput == null)
|
||||
fileDataInput = new RandomAccessFile(fullPath, "r");
|
||||
|
||||
fileSize = (int) fileDataInput.length();
|
||||
|
||||
int off =
|
||||
(offset >= 0) ? ((offset < (fileSize - blockSize)) ? offset : (fileSize - blockSize)) : 0;
|
||||
|
||||
if (off < 0)
|
||||
off = 0;
|
||||
|
||||
blockOffset = off;
|
||||
|
||||
if (block == null)
|
||||
block = new byte[blockSize];
|
||||
|
||||
// fileDataInput.seek(blockOffset);
|
||||
// fileDataInput.read(block, 0, blockSize);
|
||||
// fileDataInput.close();
|
||||
|
||||
FileChannel fc = fileDataInput.getChannel();
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(block);
|
||||
Buffer buffer = (Buffer) byteBuffer;
|
||||
fc.read(byteBuffer, blockOffset);
|
||||
buffer.clear();
|
||||
byteBuffer.get(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
895
src/main/java/definition/PDS/PDSImage.java
Normal file
895
src/main/java/definition/PDS/PDSImage.java
Normal file
@@ -0,0 +1,895 @@
|
||||
package definition.PDS;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import util.JCATLog;
|
||||
|
||||
public class PDSImage {
|
||||
public enum ImageDataTypes {
|
||||
IntegerType, ShortType, ByteType, FloatType, DoubleType, UnsignedShortType, UnsignedIntType, UnknownDataType
|
||||
};
|
||||
|
||||
public enum ImageBandTypes {
|
||||
BandInterleaved, BandSequential, LineInterleaved, LineSequential, UnknownBandType
|
||||
};
|
||||
|
||||
public enum ImageByteOrderTypes {
|
||||
Intel, NonIntel, UnknownByteOrderType
|
||||
};
|
||||
|
||||
public static String linesKey = "LINES";
|
||||
public static String samplesKey = "LINE_SAMPLES";
|
||||
public static String sampleTypeKey = "SAMPLE_TYPE";
|
||||
public static String sampleBitsKey = "SAMPLE_BITS";
|
||||
public static String bandCountKey = "BANDS";
|
||||
public static String bandNameKey = "BAND_NAME";
|
||||
public static String bandStorageKey = "BAND_STORAGE_TYPE";
|
||||
|
||||
public static int typicalPageSize = 4096;
|
||||
public static int smallPageSize = 512;
|
||||
|
||||
public int imageDataOffset = 0;
|
||||
|
||||
public long imageWidth = 0;
|
||||
public long imageHeight = 0;
|
||||
public int dataBitCount = 8;
|
||||
public String dataTypeString = "";
|
||||
|
||||
public String bandStorageType = "";
|
||||
public int bandCount = 1;
|
||||
public Vector<String> bandNames = new Vector<String>();
|
||||
|
||||
public boolean unsignedFlag = false;
|
||||
public boolean pcFlag = false;
|
||||
|
||||
public ImageDataTypes dataType = ImageDataTypes.ByteType;
|
||||
public ImageBandTypes bandType = ImageBandTypes.BandSequential;
|
||||
public ImageByteOrderTypes byteOrderType = ImageByteOrderTypes.NonIntel;
|
||||
|
||||
public String filename = null;
|
||||
// public DataInputStream fileDataInput = null;
|
||||
// public RandomAccessFile fileDataInput = null;
|
||||
public BlockFile imgBlockFile = null;
|
||||
public int pdsBlockSize = 4096;
|
||||
public PDSLabel pdsLabel = null;
|
||||
public boolean validImage = false;
|
||||
|
||||
public PDSObject imgObject = null;
|
||||
|
||||
public PDSImage() {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating PDSObject object");
|
||||
}
|
||||
// creates object
|
||||
|
||||
public PDSImage(String imgFilename, PDSObject imgObj) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating PDSObject object");
|
||||
createImage(imgFilename, imgObj);
|
||||
}
|
||||
// creates object & executes createImage method from explicit parameters
|
||||
|
||||
public PDSImage(String imgFilename, PDSObject imgObj, int bufferSize) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating PDSObject object");
|
||||
pdsBlockSize = bufferSize;
|
||||
createImage(imgFilename, imgObj);
|
||||
}
|
||||
// creates object & executes createImage method from first 2 explicit
|
||||
// parameters
|
||||
// sets size of image block
|
||||
|
||||
public PDSImage(String imgFilename) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating PDSObject object");
|
||||
}
|
||||
// creates object & does nothing with filename
|
||||
|
||||
public PDSImage(String imgFilename, long w, long h, int bitsPerPixel) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating PDSObject object");
|
||||
createImage(imgFilename, w, h, bitsPerPixel);
|
||||
}
|
||||
// creates object & executes createImage method w/ name, width, height, and
|
||||
// bits per pixel
|
||||
|
||||
public void cacheEntireImage() {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method cacheEntireImage ");
|
||||
if (imgBlockFile != null) {
|
||||
try {
|
||||
// imgBlockFile.readEntireFile();
|
||||
imgBlockFile.openFile();
|
||||
} catch (IOException ioex) {
|
||||
System.out.println("PDSImage.cacheEntireImage: " + ioex);
|
||||
ioex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
// if a blockfile exists, and it won't open, display the error
|
||||
|
||||
public void createImage(String imgFilename, PDSObject imgObj, int bufferSize) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method createImage 3 parameters ");
|
||||
pdsBlockSize = bufferSize;
|
||||
createImage(imgFilename, imgObj);
|
||||
}
|
||||
// runs the create image command but also sets PDSblocksize as buffersize
|
||||
|
||||
public void createImage(String imgFilename, PDSObject imgObj) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method createImage 2 parameters ");
|
||||
if (imgObj != null) // if imgObj exists run the following
|
||||
{
|
||||
if (imgObj.hasParameter(PDSImage.linesKey) && imgObj.hasParameter(PDSImage.samplesKey)
|
||||
&& imgObj.hasParameter(PDSImage.sampleTypeKey)
|
||||
&& imgObj.hasParameter(PDSImage.sampleBitsKey)) {
|
||||
imageHeight = imgObj.getInt(PDSImage.linesKey);
|
||||
imageWidth = imgObj.getInt(PDSImage.samplesKey);
|
||||
dataTypeString = imgObj.getString(PDSImage.sampleTypeKey);
|
||||
dataBitCount = imgObj.getInt(sampleBitsKey);
|
||||
// reads LINES, LINE_SAMPLES, SAMPLE_TYPE & SAMPLE_BITS
|
||||
|
||||
if (dataTypeString.contains("UNSIGNED"))
|
||||
unsignedFlag = true;
|
||||
// if there the sample type is unsigned, set the flag
|
||||
if (dataTypeString.contains("PC"))
|
||||
byteOrderType = ImageByteOrderTypes.Intel;
|
||||
// if the data type contains PC set byte order type to Intel
|
||||
|
||||
if (dataTypeString.contains("INTEGER")) {
|
||||
if (dataBitCount == 16)
|
||||
dataType = ImageDataTypes.ShortType;
|
||||
else if (dataBitCount == 8)
|
||||
dataType = ImageDataTypes.ByteType;
|
||||
else if (dataBitCount == 32)
|
||||
dataType = ImageDataTypes.IntegerType;
|
||||
} // if the SAMPLE_TYPE has INTEGER, it finds out which type
|
||||
// using SAMPLE_BITS and then sets data type
|
||||
else if (dataTypeString.contains("REAL")) {
|
||||
if (dataBitCount == 32)
|
||||
dataType = ImageDataTypes.FloatType;
|
||||
else if (dataBitCount == 64)
|
||||
dataType = ImageDataTypes.DoubleType;
|
||||
} // if the SAMPLE_TYPE contains REAL, the datatype is set
|
||||
// according to SAMPLE_BITS
|
||||
else if (dataTypeString.contains("DOUBLE")) {
|
||||
dataType = ImageDataTypes.DoubleType;
|
||||
} // if the SAMPLE_TYPE is double, sets datatype to double
|
||||
|
||||
if (imgObj.hasParameter(PDSImage.bandCountKey)) // tests for
|
||||
// BANDS in lbl
|
||||
// file
|
||||
{
|
||||
bandCount = imgObj.getInt(PDSImage.bandCountKey);
|
||||
// sets bandCount to whatever follows BANDS in lbl file
|
||||
String storageType = imgObj.getString(PDSImage.bandStorageKey);
|
||||
// sets storagetype to BAND_STORAGE_TYPE in lbl file
|
||||
if (storageType.contains("BAND_SEQUENTIAL"))
|
||||
bandType = ImageBandTypes.BandSequential; // sets as
|
||||
// BandSequential
|
||||
// if so
|
||||
else if (storageType.contains("LINE_INTERLEAVED"))
|
||||
bandType = ImageBandTypes.LineInterleaved; // sets as
|
||||
// LineInterleaved
|
||||
// if so
|
||||
else
|
||||
bandType = ImageBandTypes.BandInterleaved; // sets as
|
||||
// BandInterleaved
|
||||
// if so
|
||||
|
||||
if (imgObj.hasParameter(PDSImage.bandNameKey)) // does stuff
|
||||
// if there
|
||||
// is a band
|
||||
// name, but
|
||||
// I don't
|
||||
// have an
|
||||
// LBL with
|
||||
// one
|
||||
// sooo...
|
||||
{
|
||||
String bandString =
|
||||
imgObj.getString(PDSImage.bandNameKey).replace('(', ' ').replace(')', ' ');
|
||||
// split on ", then strip off the leading quote
|
||||
String bandSplit[] = bandString.split("\",");
|
||||
for (int i = 0; i < bandSplit.length; i++)
|
||||
bandNames.add(bandSplit[i].replace("\"", ""));
|
||||
}
|
||||
}
|
||||
|
||||
File f = new File(imgFilename);
|
||||
// creates a File obj named f with the directory path specified
|
||||
if (f.exists()) // if that file exists do the following
|
||||
{
|
||||
validImage = true;
|
||||
// it is a valid image
|
||||
filename = new String(imgFilename);
|
||||
// a string with the filename is created
|
||||
openImageFile();
|
||||
// opens the image file
|
||||
if (PDSLabel.isLabelFile(imgFilename)) // if a label file
|
||||
// exists with
|
||||
// filename
|
||||
{
|
||||
// RECORD_TYPE = FIXED_LENGTH
|
||||
// RECORD_BYTES = 2880
|
||||
// FILE_RECORDS = 1922
|
||||
// LABEL_RECORDS = 2
|
||||
|
||||
PDSLabel lbl = new PDSLabel(imgFilename);
|
||||
|
||||
int recBytes = lbl.getInt("RECORD_BYTES");
|
||||
int lblRecs = lbl.getInt("LABEL_RECORDS");
|
||||
//
|
||||
imageDataOffset = recBytes * lblRecs;
|
||||
// set a new image data offset
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// creates an image with the provided information
|
||||
//
|
||||
|
||||
public void createImage(String imgFilename, long w, long h, int bitsPerPixel) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method createImage ");
|
||||
File f = new File(imgFilename);
|
||||
if (f.exists()) {
|
||||
filename = new String(imgFilename);
|
||||
long fileSize = f.length();
|
||||
long calculatedFileSize = w * h;
|
||||
|
||||
openImageFile();
|
||||
|
||||
switch (bitsPerPixel) {
|
||||
case 8:
|
||||
dataType = ImageDataTypes.ByteType;
|
||||
break;
|
||||
case 16:
|
||||
dataType = ImageDataTypes.ShortType;
|
||||
break;
|
||||
case 32:
|
||||
dataType = ImageDataTypes.IntegerType;
|
||||
break;
|
||||
case 64:
|
||||
dataType = ImageDataTypes.DoubleType;
|
||||
break;
|
||||
default:
|
||||
dataType = ImageDataTypes.ByteType;
|
||||
break;
|
||||
}
|
||||
// breaks image file up by pixel according to the datatype specified
|
||||
|
||||
switch (dataType) {
|
||||
case IntegerType:
|
||||
calculatedFileSize *= 4;
|
||||
break;
|
||||
case ShortType:
|
||||
calculatedFileSize *= 2;
|
||||
break;
|
||||
case FloatType:
|
||||
calculatedFileSize *= 4;
|
||||
break;
|
||||
case DoubleType:
|
||||
calculatedFileSize *= 8;
|
||||
break;
|
||||
case ByteType:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// breaks up data type based on calculated file size
|
||||
|
||||
if (calculatedFileSize > 0)// && (calculatedFileSize == fileSize))
|
||||
{
|
||||
imageWidth = w;
|
||||
imageHeight = h;
|
||||
validImage = true;
|
||||
} // tests to make sure file size is positive
|
||||
else if (fileSize > calculatedFileSize) // if actual filesize is
|
||||
// bigger than calculated
|
||||
// size
|
||||
{
|
||||
// image data may be preceded by a label, so first we want to
|
||||
// decode the label
|
||||
pdsLabel = new PDSLabel(imgFilename);
|
||||
if (pdsLabel.isValidLabel()) {
|
||||
int recordBytes = pdsLabel.getInt("RECORD_BYTES");
|
||||
int numRecords = pdsLabel.getInt("FILE_RECORDS");
|
||||
PDSObject imgObj = pdsLabel.findObject("IMAGE");
|
||||
|
||||
if (imgObj != null) {
|
||||
int numLines = imgObj.getInt("LINES");
|
||||
int samples = imgObj.getInt("LINE_SAMPLES");
|
||||
int sampleBits = imgObj.getInt("SAMPLE_BITS");
|
||||
|
||||
if ((sampleBits == 0) && (samples != 0)) {
|
||||
sampleBits = recordBytes / samples;
|
||||
}
|
||||
|
||||
imageWidth = samples;
|
||||
imageHeight = numLines;
|
||||
imageDataOffset = (numRecords - numLines) * recordBytes;
|
||||
|
||||
validImage = true;
|
||||
|
||||
switch (sampleBits) {
|
||||
case 8:
|
||||
dataType = ImageDataTypes.ByteType;
|
||||
break;
|
||||
case 16:
|
||||
dataType = ImageDataTypes.ShortType;
|
||||
break;
|
||||
case 32:
|
||||
dataType = ImageDataTypes.IntegerType;
|
||||
break;
|
||||
case 64:
|
||||
dataType = ImageDataTypes.DoubleType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// this method enables the retrieval of a band index from a name
|
||||
//
|
||||
|
||||
public int findBandNumber(String name) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method findBandNumber ");
|
||||
int result = -1;
|
||||
|
||||
int size = bandNames.size();
|
||||
|
||||
String upperName = name.trim().toUpperCase();
|
||||
|
||||
for (int i = 0; (i < size) && (result < 0); i++) {
|
||||
String itemName = bandNames.get(i).trim().toUpperCase();
|
||||
if (upperName.equals(itemName)) {
|
||||
result = i;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isValidImage() {
|
||||
return validImage;
|
||||
}
|
||||
|
||||
public long getWidth() {
|
||||
return imageWidth;
|
||||
}
|
||||
|
||||
public long getHeight() {
|
||||
return imageHeight;
|
||||
}
|
||||
|
||||
public boolean openImageFile() {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method openImageFile ");
|
||||
boolean result = false;
|
||||
|
||||
if (imgBlockFile != null) {
|
||||
result = true;
|
||||
} else {
|
||||
try {
|
||||
// fileDataInput = new DataInputStream(new
|
||||
// FileInputStream(filename));
|
||||
if (filename != null)
|
||||
imgBlockFile = new BlockFile(filename, pdsBlockSize);
|
||||
// fileDataInput.seek(imageDataOffset);
|
||||
result = true;
|
||||
} catch (Exception e) {
|
||||
System.out.println("PDSImage.openImageFile: " + e);
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void closeImageFile() {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method closeImageFile ");
|
||||
if (imgBlockFile != null) {
|
||||
try {
|
||||
imgBlockFile.closeFile();
|
||||
} catch (Exception e) {
|
||||
System.out.println("PDSImage.closeImageFile: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
imgBlockFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
public byte readByte() {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method readByte ");
|
||||
byte result = 0;
|
||||
|
||||
if (openImageFile()) {
|
||||
try {
|
||||
result = imgBlockFile.readByte(imgBlockFile.blockOffset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.readByte: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public short readShort() {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method readShort ");
|
||||
short result = 0;
|
||||
|
||||
if (openImageFile()) {
|
||||
try {
|
||||
result = imgBlockFile.readShort(imgBlockFile.blockOffset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.readByte: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// reading a byte from the file given the zero-based row and column indices
|
||||
//
|
||||
|
||||
public byte getByteValue(int row, int col) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method getByteValue 2 parameters ");
|
||||
byte result = 0;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
long pixelSize = getPixelSize();
|
||||
|
||||
// long offset = (row * imageWidth + col) * pixelSize +
|
||||
// imageDataOffset;
|
||||
long offset = (row * imageWidth * bandCount + col) * pixelSize + imageDataOffset;
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
result = imgBlockFile.readByte((int) offset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// reading a short from the file given the zero-based row and column indices
|
||||
//
|
||||
|
||||
public short getShortValue(int row, int col) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method getShortValue 2 parameters ");
|
||||
short result = 0;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
long pixelSize = getPixelSize();
|
||||
|
||||
// long offset = (row * imageWidth + col) * pixelSize +
|
||||
// imageDataOffset;
|
||||
long offset = (row * imageWidth * bandCount + col) * pixelSize + imageDataOffset;
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
result = imgBlockFile.readShort((int) offset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// reading a short from the file given the zero-based row and column indices
|
||||
//
|
||||
public short getShortValue(long offset) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method getShortValue 1 parameter ");
|
||||
short result = 0;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
// long pixelSize = getPixelSize();
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
result = imgBlockFile.readShort((int) offset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// reading an int from the file given the zero-based row and column indices
|
||||
//
|
||||
|
||||
public int getIntValue(int row, int col) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method getIntValue 2 parameters ");
|
||||
int result = 0;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
long pixelSize = getPixelSize();
|
||||
|
||||
// long offset = (row * imageWidth + col) * pixelSize +
|
||||
// imageDataOffset;
|
||||
long offset = (row * imageWidth * bandCount + col) * pixelSize + imageDataOffset;
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
result = imgBlockFile.readInt((int) offset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// reading a float from the file given the zero-based row and column indices
|
||||
//
|
||||
|
||||
public float getFloatValue(int row, int col) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method getFloatValue 2 parameters ");
|
||||
float result = 0.0f;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
long pixelSize = getPixelSize();
|
||||
|
||||
// long offset = (row * imageWidth + col) * pixelSize +
|
||||
// imageDataOffset;
|
||||
long offset = (row * imageWidth * bandCount + col) * pixelSize + imageDataOffset;
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
result = imgBlockFile.readFloat((int) offset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// reading a double from the file given the zero-based row and column
|
||||
// indices
|
||||
//
|
||||
|
||||
public double getDoubleValue(int row, int col) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method getDoubleValue 2 parameters ");
|
||||
double result = 0.0;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
long pixelSize = getPixelSize();
|
||||
|
||||
// long offset = (row * imageWidth + col) * pixelSize +
|
||||
// imageDataOffset;
|
||||
long offset = (row * imageWidth * bandCount + col) * pixelSize + imageDataOffset;
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
result = imgBlockFile.readDouble((int) offset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// reading a byte from the file given the zero-based row, column, and band
|
||||
// indices
|
||||
//
|
||||
|
||||
public byte getByteValue(int row, int col, int band) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method getByteValue 3 parameters ");
|
||||
byte result = 0;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
long pixelSize = getPixelSize();
|
||||
|
||||
long bandSize = (imageWidth * imageHeight) * pixelSize;
|
||||
long offset = bandSize * band + (row * imageWidth + col) * pixelSize + imageDataOffset;
|
||||
if (bandType == ImageBandTypes.BandInterleaved)
|
||||
offset = ((row * imageWidth + col) * bandCount + band) * pixelSize + imageDataOffset;
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
result = imgBlockFile.readByte((int) offset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// reading a short from the file given the zero-based row, column, and band
|
||||
// indices
|
||||
//
|
||||
|
||||
public short getShortValue(int row, int col, int band) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method getShortValue 3 parameters ");
|
||||
short result = 0;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
long pixelSize = getPixelSize();
|
||||
|
||||
long bandSize = (imageWidth * imageHeight) * pixelSize;
|
||||
long offset = bandSize * band + (row * imageWidth + col) * pixelSize + imageDataOffset;
|
||||
if (bandType == ImageBandTypes.BandInterleaved)
|
||||
offset = ((row * imageWidth + col) * bandCount + band) * pixelSize + imageDataOffset;
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
result = imgBlockFile.readShort((int) offset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// reading an integer from the file given the zero-based row, column, and
|
||||
// band indices
|
||||
//
|
||||
|
||||
public int getIntValue(int row, int col, int band) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method getIntValue 3 parameters ");
|
||||
int result = 0;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
long pixelSize = getPixelSize();
|
||||
|
||||
long bandSize = (imageWidth * imageHeight) * pixelSize;
|
||||
long offset = bandSize * band + (row * imageWidth + col) * pixelSize + imageDataOffset;
|
||||
if (bandType == ImageBandTypes.BandInterleaved)
|
||||
offset = ((row * imageWidth + col) * bandCount + band) * pixelSize + imageDataOffset;
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
result = imgBlockFile.readInt((int) offset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// reading a float from the file given the zero-based row, column, and band
|
||||
// indices
|
||||
//
|
||||
|
||||
public float getFloatValue(int row, int col, int band) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method getFloatValue 3 parameters ");
|
||||
float result = 0.0f;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
long pixelSize = getPixelSize();
|
||||
|
||||
long bandSize = (imageWidth * imageHeight) * pixelSize;
|
||||
long offset = bandSize * band + (row * imageWidth + col) * pixelSize + imageDataOffset;
|
||||
if (bandType == ImageBandTypes.BandInterleaved) {
|
||||
// offset = row * imageWidth * pixelSize * bandCount + band
|
||||
// * imageWidth * pixelSize + col * pixelSize;
|
||||
offset = ((row * bandCount + band) * imageWidth + col) * pixelSize;
|
||||
// offset = ((row * imageWidth + col) * bandCount + band) *
|
||||
// pixelSize + imageDataOffset;
|
||||
} else if (bandType == ImageBandTypes.LineInterleaved) {
|
||||
// long lineSize = imageWidth * pixelSize;
|
||||
// offset = row * bandCount * lineSize + band*lineSize + col
|
||||
// * pixelSize;
|
||||
// offset = row * bandCount * imageWidth * pixelSize + band
|
||||
// * imageWidth * pixelSize + col * pixelSize;
|
||||
offset = (row * bandCount * imageWidth + band * imageWidth + col) * pixelSize;
|
||||
}
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
result = imgBlockFile.readFloat((int) offset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// reading a float from the file given the zero-based row, column, and band
|
||||
// indices
|
||||
//
|
||||
|
||||
public float getPCFloatValue(int row, int col, int band) {
|
||||
|
||||
float result = 0.0f;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
long pixelSize = getPixelSize();
|
||||
|
||||
long bandSize = (imageWidth * imageHeight) * pixelSize;
|
||||
long offset = bandSize * band + (row * imageWidth + col) * pixelSize + imageDataOffset;
|
||||
if (bandType == ImageBandTypes.BandInterleaved) {
|
||||
// offset = row * imageWidth * pixelSize * bandCount + band
|
||||
// * imageWidth * pixelSize + col * pixelSize;
|
||||
offset = ((row * bandCount + band) * imageWidth + col) * pixelSize;
|
||||
// offset = ((row * imageWidth + col) * bandCount + band) *
|
||||
// pixelSize + imageDataOffset;
|
||||
} else if (bandType == ImageBandTypes.LineInterleaved) {
|
||||
// long lineSize = imageWidth * pixelSize;
|
||||
// offset = row * bandCount * lineSize + band*lineSize + col
|
||||
// * pixelSize;
|
||||
// offset = row * bandCount * imageWidth * pixelSize + band
|
||||
// * imageWidth * pixelSize + col * pixelSize;
|
||||
offset = (row * bandCount * imageWidth + band * imageWidth + col) * pixelSize;
|
||||
}
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
if (imgBlockFile != null)
|
||||
result = imgBlockFile.readPCFloat((int) offset);
|
||||
} catch (Exception e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
System.out.printf("Row %d Col %d Band %d offset %d\n", row, col, band, offset);
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// reading a double from the file given the zero-based row, column, and band
|
||||
// indices
|
||||
//
|
||||
|
||||
public double getDoubleValue(int row, int col, int band) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method getDoubleValue 3 parameters ");
|
||||
double result = 0.0;
|
||||
|
||||
if (openImageFile()) {
|
||||
// if (dataType == ImageDataTypes.ShortType)
|
||||
{
|
||||
long pixelSize = getPixelSize();
|
||||
|
||||
long bandSize = (imageWidth * imageHeight) * pixelSize;
|
||||
long offset = bandSize * band + (row * imageWidth + col) * pixelSize + imageDataOffset;
|
||||
if (bandType == ImageBandTypes.BandInterleaved)
|
||||
offset = ((row * imageWidth + col) * bandCount + band) * pixelSize + imageDataOffset;
|
||||
|
||||
try {
|
||||
// fileDataInput.skip(offset);
|
||||
// fileDataInput.seek(offset);
|
||||
result = imgBlockFile.readDouble((int) offset);
|
||||
} catch (IOException e) {
|
||||
System.out.println("PDSImage.getShortValue: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getPixelSize() {
|
||||
int result = 1;
|
||||
|
||||
switch (dataType) {
|
||||
case IntegerType:
|
||||
result = 4;
|
||||
break;
|
||||
case ShortType:
|
||||
result = 2;
|
||||
break;
|
||||
case FloatType:
|
||||
result = 4;
|
||||
break;
|
||||
case DoubleType:
|
||||
result = 8;
|
||||
break;
|
||||
case ByteType:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static BufferedImage pdsImage2Image(String filename) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method pdsImage2Image ");
|
||||
BufferedImage result = null;
|
||||
|
||||
PDSImage img = new PDSImage(filename, 0, 0, 8);
|
||||
if (img.isValidImage()) {
|
||||
long w = img.getWidth();
|
||||
long h = img.getHeight();
|
||||
|
||||
if ((w > 0) && (h > 0)) {
|
||||
result = new BufferedImage((int) w, (int) h, BufferedImage.TYPE_3BYTE_BGR);
|
||||
if (result != null) {
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int v = img.readByte();
|
||||
result.setRGB(j, i, (int) (((v & 0xff) << 16) | ((v & 0xff) << 8) | (v & 0xff)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
303
src/main/java/definition/PDS/PDSLabel.java
Normal file
303
src/main/java/definition/PDS/PDSLabel.java
Normal file
@@ -0,0 +1,303 @@
|
||||
package definition.PDS;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.commons.math3.util.Pair;
|
||||
|
||||
import util.FileUtils;
|
||||
import util.JCATLog;
|
||||
|
||||
public class PDSLabel extends PDSObject {
|
||||
protected String lblFilename = null;
|
||||
protected boolean validLabel = false;
|
||||
|
||||
public PDSLabel(String filename) {
|
||||
|
||||
super(filename);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating PDSLabel object");
|
||||
readLabel(filename);
|
||||
|
||||
}
|
||||
|
||||
public boolean isValidLabel() {
|
||||
return validLabel;
|
||||
}
|
||||
|
||||
public boolean readLabel(String filename) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method readLabel");
|
||||
|
||||
boolean result = false;
|
||||
|
||||
// if (!PDSLabel.isLabelFile(filename))
|
||||
// return result;
|
||||
|
||||
lblFilename = new String(filename);
|
||||
|
||||
try {
|
||||
Vector<String> txtLines = new Vector<String>();// readLabelFile(filename);
|
||||
FileUtils.readAsciiFile(filename, txtLines);
|
||||
Vector<String> lblLines = new Vector<String>();
|
||||
|
||||
String currentLine = new String("");
|
||||
|
||||
int size = txtLines.size();
|
||||
int i;
|
||||
|
||||
boolean inQuote = false;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
String s = txtLines.get(i).trim();
|
||||
if (s.length() > 0) {
|
||||
// strip out comments, from
|
||||
// https://blog.ostermiller.org/find-comment
|
||||
s = s.replaceAll("(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)", "");
|
||||
int qCount = getQuoteCount(s);
|
||||
if (inQuote) {
|
||||
currentLine += s;
|
||||
} else {
|
||||
if (checkForEquals(s)) {
|
||||
if (currentLine.length() > 0) {
|
||||
|
||||
lblLines.add(currentLine);
|
||||
currentLine = new String("");
|
||||
}
|
||||
}
|
||||
String line = new String(currentLine.trim());
|
||||
if (line.startsWith("/*") && line.endsWith("*/")) {
|
||||
} else {
|
||||
currentLine += ((currentLine.length() > 0) ? " " : "") + s;
|
||||
}
|
||||
}
|
||||
|
||||
if (qCount == 1) {
|
||||
inQuote = false;
|
||||
}
|
||||
|
||||
if (s.toUpperCase().equals("END"))
|
||||
i = size;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentLine.trim().length() > 0) {
|
||||
lblLines.add(currentLine);
|
||||
}
|
||||
|
||||
processLabelLines(lblLines);
|
||||
|
||||
result = true;
|
||||
} catch (Exception e) {
|
||||
System.out.println("LabelReader.readLabel: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void processLabelLines(Vector<String> lines) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method processLabelLines");
|
||||
|
||||
int i;
|
||||
int size = lines.size();
|
||||
|
||||
Vector<PDSObject> subObjs = new Vector<PDSObject>();
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
String line = lines.get(i);
|
||||
|
||||
// System.out.printf("processLabelLines: %s\n", line);
|
||||
|
||||
|
||||
String parts[] = line.trim().split("=");
|
||||
|
||||
if (parts.length >= 2) {
|
||||
if (i == 0) {
|
||||
if (parts[0].trim().equals("PDS_VERSION_ID"))
|
||||
validLabel = true;
|
||||
}
|
||||
|
||||
if (parts[0].trim().toUpperCase().equals("OBJECT")) {
|
||||
PDSObject o = new PDSObject(parts[1].trim());
|
||||
subObjs.add(o);
|
||||
} else if (parts[0].trim().toUpperCase().equals("END_OBJECT")) {
|
||||
int subSize = subObjs.size();
|
||||
|
||||
if (subSize == 0) {
|
||||
System.out.println("We hit an END_OBJECT without having a corresponding OBJECT.");
|
||||
} else if (subSize == 1) {
|
||||
addObject(subObjs.get(0));
|
||||
subObjs.clear();
|
||||
} else if (size > 1) {
|
||||
PDSObject lastObj = subObjs.get(subSize - 1);
|
||||
PDSObject nextToLast = subObjs.get(subSize - 2);
|
||||
|
||||
nextToLast.addObject(lastObj);
|
||||
subObjs.remove(subSize - 1);
|
||||
}
|
||||
} else {
|
||||
int subSize = subObjs.size();
|
||||
|
||||
if (subSize > 0) {
|
||||
subObjs.get(subSize - 1).addParameter(parts[0].trim(), parts[1].trim());
|
||||
// System.out.println(o.objectName + "." +
|
||||
// parts[0].trim() + " = " + parts[1].trim());
|
||||
} else {
|
||||
params.add(new Pair<String, String>(parts[0].trim(), parts[1].trim()));
|
||||
// System.out.println(parts[0].trim() + " = " +
|
||||
// parts[1].trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean checkForEquals(String s) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method checkForEquals");
|
||||
|
||||
boolean result = false;
|
||||
|
||||
boolean inQuote = false;
|
||||
|
||||
int length = s.length();
|
||||
for (int i = 0; (i < length) && !result; i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c == '"') {
|
||||
inQuote = inQuote ? false : true;
|
||||
}
|
||||
if (!inQuote && (c == '=')) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected int getQuoteCount(String s) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method getQuoteCount");
|
||||
|
||||
int result = 0;
|
||||
|
||||
int length = s.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c == '"') {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Vector<String> readLabelFile(String filename) throws Exception {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method readLabelFile");
|
||||
|
||||
Vector<String> results = new Vector<String>();
|
||||
|
||||
File f = new File(filename);
|
||||
if (f.exists()) {
|
||||
FileInputStream fileInput = new FileInputStream(filename);
|
||||
BufferedReader fileRdr = new BufferedReader(new InputStreamReader(fileInput));
|
||||
|
||||
String s = new String(fileRdr.readLine().trim());
|
||||
|
||||
if (s.trim().toUpperCase().startsWith("PDS_VERSION_ID")) {
|
||||
while (s != null) {
|
||||
|
||||
results.add(s);
|
||||
|
||||
if (s.trim().toUpperCase().equals("END")) {
|
||||
break;
|
||||
}
|
||||
|
||||
s = fileRdr.readLine();
|
||||
}
|
||||
}
|
||||
|
||||
fileRdr.close();
|
||||
fileInput.close();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static boolean isLabelFile(String filename) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method isLabelFile");
|
||||
|
||||
boolean result = false;
|
||||
|
||||
File f = new File(filename);
|
||||
if (f.exists()) {
|
||||
try {
|
||||
FileInputStream fileInput = new FileInputStream(filename);
|
||||
// DataInputStream fileRdr = new DataInputStream(fileInput);
|
||||
BufferedReader fileRdr = new BufferedReader(new InputStreamReader(fileInput));
|
||||
|
||||
try {
|
||||
String testStr = new String("");
|
||||
|
||||
final int maxChars = 512;
|
||||
int nCharsRead = 0;
|
||||
char[] buff = new char[maxChars];
|
||||
|
||||
try {
|
||||
nCharsRead = fileRdr.read(buff, 0, maxChars);
|
||||
} catch (EOFException eofEx) {
|
||||
}
|
||||
|
||||
if (nCharsRead > 0) {
|
||||
testStr = new String(buff);
|
||||
if (testStr.contains("PDS_VERSION_ID")) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
} catch (IOException ioEx) {
|
||||
}
|
||||
|
||||
try {
|
||||
fileRdr.close();
|
||||
fileInput.close();
|
||||
} catch (IOException io2Ex) {
|
||||
}
|
||||
} catch (FileNotFoundException fnfEx) {
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void getLabelStrings(String lblFilename, Vector<String> lines) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method getLabelStrings");
|
||||
|
||||
getObjectStrings(lines);
|
||||
|
||||
lines.add("END");
|
||||
}
|
||||
|
||||
public static void main(String[] argv) {
|
||||
// PDSLabel lbl = new
|
||||
// PDSLabel("C:\\dev\\apps\\crism\\mola\\megr44s090hb.lbl");
|
||||
// PDSLabel lbl = new
|
||||
// PDSLabel("C:\\Data\\crism_pds_archive\\2006_347\\EDR\\FRT000035DB_07_SC164L_EDR0.LBL");
|
||||
PDSLabel lbl =
|
||||
new PDSLabel("C:\\Data\\crism_pds_archive\\2006_347\\DDR\\FRT000035DB_07_DE164S_DDR1.LBL");
|
||||
// "C:\\Data\\crism_pds_archive\\2006_347\\DDR\\FRT000035DB_07_DE164S_DDR1.IMG"
|
||||
if (lbl != null) {
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
276
src/main/java/definition/PDS/PDSObject.java
Normal file
276
src/main/java/definition/PDS/PDSObject.java
Normal file
@@ -0,0 +1,276 @@
|
||||
package definition.PDS;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.commons.math3.util.Pair;
|
||||
|
||||
import util.FileUtils;
|
||||
import util.JCATLog;
|
||||
|
||||
public class PDSObject {
|
||||
protected String objectName = null;
|
||||
protected Vector<Pair<String, String>> params = new Vector<Pair<String, String>>();
|
||||
protected Vector<PDSObject> subObjects = new Vector<PDSObject>();
|
||||
|
||||
public PDSObject(String objName) {
|
||||
|
||||
// if(objName==null)
|
||||
// return;
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating PDSObject object");
|
||||
|
||||
objectName = new String(objName);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public PDSObject(PDSObject obj) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating PDSObject object");
|
||||
copy(obj);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return objectName;
|
||||
}
|
||||
|
||||
public void copy(PDSObject obj) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method copy");
|
||||
|
||||
int i, size;
|
||||
|
||||
params.clear();
|
||||
subObjects.clear();
|
||||
|
||||
objectName = obj.objectName;
|
||||
|
||||
size = obj.params.size();
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
Pair<String, String> inPair = obj.params.get(i);
|
||||
|
||||
Pair<String, String> outPair =
|
||||
new Pair<String, String>(new String(inPair.getFirst()), new String(inPair.getSecond()));
|
||||
params.add(outPair);
|
||||
}
|
||||
|
||||
size = obj.subObjects.size();
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
PDSObject pdsObj = new PDSObject(obj.subObjects.get(i));
|
||||
subObjects.add(pdsObj);
|
||||
}
|
||||
}
|
||||
|
||||
public void addObject(PDSObject obj) {
|
||||
subObjects.add(obj);
|
||||
}
|
||||
|
||||
public void removeObject(int index) {
|
||||
if ((index >= 0) && (index < subObjects.size())) {
|
||||
subObjects.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearObjects() {
|
||||
subObjects.clear();
|
||||
}
|
||||
|
||||
public PDSObject getObject(int index) {
|
||||
PDSObject result = null;
|
||||
|
||||
if ((index >= 0) && (index < subObjects.size())) {
|
||||
result = subObjects.get(index);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getObjectCount() {
|
||||
return subObjects.size();
|
||||
}
|
||||
|
||||
public PDSObject findObject(String objKey) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method findObject");
|
||||
|
||||
PDSObject result = null;
|
||||
|
||||
int size = subObjects.size();
|
||||
for (int i = 0; (i < size) && (result == null); i++) {
|
||||
if (objKey.equals(subObjects.get(i).objectName)) {
|
||||
result = subObjects.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addParameter(String key, String value) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method addParameter");
|
||||
|
||||
Pair<String, String> p = new Pair<String, String>(key, value);
|
||||
params.add(p);
|
||||
}
|
||||
|
||||
public void addOrReplaceParameter(String key, String value) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method addOrReplaceParameter");
|
||||
|
||||
Pair<String, String> p = findParameter(key);
|
||||
if (p != null) {
|
||||
params.remove(p);
|
||||
}
|
||||
p = new Pair<String, String>(key, value);
|
||||
params.add(p);
|
||||
}
|
||||
|
||||
public String getString(String key) {
|
||||
String result = null;
|
||||
|
||||
Pair<String, String> p = findParameter(key);
|
||||
if (p != null) {
|
||||
result = new String(p.getSecond());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getStringNoQuotes(String key) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method getStringNoQuotes");
|
||||
|
||||
String a = getString(key);
|
||||
|
||||
if (a == null)
|
||||
return "";
|
||||
|
||||
String result = new String(FileUtils.stripDoubleQuotes(getString(key).trim()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public double getDouble(String key) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method getDouble");
|
||||
|
||||
Pair<String, String> p = findParameter(key);
|
||||
String[] values = p.getSecond().split("\\s+");
|
||||
double result = Double.valueOf(values[0].trim());
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getInt(String key) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method getInt");
|
||||
Pair<String, String> p = findParameter(key);
|
||||
String[] values = p.getSecond().split("\\s+");
|
||||
int result = Integer.valueOf(values[0].trim());
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean hasParameter(String key) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method hasParameter");
|
||||
boolean result = false;
|
||||
|
||||
Pair<String, String> p = findParameter(key);
|
||||
if (p != null) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Pair<String, String> findParameter(String key) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method findParameter");
|
||||
Pair<String, String> result = null;
|
||||
|
||||
int size = params.size();
|
||||
|
||||
String upKey = key.trim().toUpperCase();
|
||||
|
||||
for (int i = 0; (i < size) && (result == null); i++) {
|
||||
Pair<String, String> p = params.get(i);
|
||||
if (p.getFirst().trim().toUpperCase().equals(upKey)) {
|
||||
result = p;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Vector<Pair<String, String>> findParameters(String key) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method findParameters");
|
||||
Vector<Pair<String, String>> results = new Vector<Pair<String, String>>();
|
||||
|
||||
int size = params.size();
|
||||
|
||||
String upKey = key.trim().toUpperCase();
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
Pair<String, String> p = params.get(i);
|
||||
if (p.getFirst().trim().toUpperCase().equals(upKey)) {
|
||||
results.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public boolean removeParameter(String key) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method removeParameter");
|
||||
boolean result = false;
|
||||
|
||||
int size = params.size();
|
||||
|
||||
String upKey = key.trim().toUpperCase();
|
||||
|
||||
for (int i = 0; (i < size) && !result; i++) {
|
||||
Pair<String, String> p = params.get(i);
|
||||
if (p.getFirst().trim().toUpperCase().equals(upKey)) {
|
||||
result = true;
|
||||
params.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void getObjectStrings(Vector<String> lines) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method getObjectStrings");
|
||||
int i, n;
|
||||
|
||||
String line;
|
||||
|
||||
n = params.size();
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
Pair<String, String> p = params.get(i);
|
||||
line = p.getFirst();
|
||||
line += " = ";
|
||||
line += p.getSecond();
|
||||
lines.add(line);
|
||||
}
|
||||
|
||||
n = subObjects.size();
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
PDSObject obj = subObjects.get(i);
|
||||
line = "OBJECT = ";
|
||||
line += obj.getName();
|
||||
lines.add(line);
|
||||
|
||||
obj.getObjectStrings(lines);
|
||||
|
||||
line = "END_OBJECT = ";
|
||||
line += obj.getName();
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
73
src/main/java/demo/CRISMPDSReader.java
Normal file
73
src/main/java/demo/CRISMPDSReader.java
Normal file
@@ -0,0 +1,73 @@
|
||||
package demo;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import reader.CRISMPDSImage;
|
||||
import reader.CRISMPDSImageNextGen;
|
||||
import reader.TRDR;
|
||||
|
||||
public class CRISMPDSReader {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
String imageFilename = "hrl0002422e_07_if182j_ter3";
|
||||
|
||||
imageFilename = "hrl0002422e_07_if182l_trr3";
|
||||
|
||||
// imageFilename = "frt000251c0_07_if165j_mtr3";
|
||||
|
||||
String filename = imageFilename + ".img";
|
||||
|
||||
CRISMPDSImage image = null;
|
||||
String basename = FilenameUtils.getBaseName(imageFilename);
|
||||
if (basename.substring(20, 21).equals("j")) {
|
||||
String wavelengthTable = imageFilename.replaceAll("if", "wv") + ".tab";
|
||||
image = new CRISMPDSImageNextGen(filename, wavelengthTable);
|
||||
} else {
|
||||
String ddrFile = imageFilename.replaceAll("if", "de").replaceAll("trr3", "ddr1") + ".img";
|
||||
image = new TRDR(filename, ddrFile);
|
||||
}
|
||||
|
||||
System.out.printf("file %s\nwidth %d height %d numBands %d\n", filename, image.getWidth(),
|
||||
image.getHeight(), image.getNumBands());
|
||||
|
||||
if (image.haveMapBounds()) {
|
||||
System.out.printf("min, max lat %f, %f (deg)\n", image.getMinLatDegrees(),
|
||||
image.getMaxLatDegrees());
|
||||
System.out.printf("west, east lon %f, %f (deg)\n", image.getWestLonDegrees(),
|
||||
image.getEastLonDegrees());
|
||||
System.out.printf("min, max line %d, %d\n", image.getMinLine(), image.getMaxLine());
|
||||
System.out.printf("min, max sample %d, %d\n", image.getMinSample(), image.getMaxSample());
|
||||
}
|
||||
|
||||
int x = 100;
|
||||
int y = 100;
|
||||
List<Integer> bandIndices = image.getBandIndices();
|
||||
List<Double> wavelengths = image.getWavelengths();
|
||||
for (int i = 0; i < wavelengths.size(); i++) {
|
||||
int bandIndex = bandIndices.get(i);
|
||||
double wavelength = wavelengths.get(i);
|
||||
double intensity = image.getPCFloatValue(y, x, bandIndex);
|
||||
System.out.printf("%d %d %f %f\n", i, bandIndex, wavelength, intensity);
|
||||
}
|
||||
|
||||
int red = 150;
|
||||
int green = 300;
|
||||
int blue = 400;
|
||||
|
||||
BufferedImage bi = image.getQuickColorImage(red, green, blue);
|
||||
try {
|
||||
ImageIO.write(bi, "JPEG", new FileOutputStream(basename + ".jpg"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1535
src/main/java/javafx/JCATCalls.java
Normal file
1535
src/main/java/javafx/JCATCalls.java
Normal file
File diff suppressed because it is too large
Load Diff
757
src/main/java/javafx/MTRDRBrowseProducts.java
Normal file
757
src/main/java/javafx/MTRDRBrowseProducts.java
Normal file
@@ -0,0 +1,757 @@
|
||||
package javafx;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
import javax.imageio.ImageIO;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.embed.swing.SwingFXUtils;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.SeparatorMenuItem;
|
||||
import javafx.scene.control.TextInputDialog;
|
||||
import javafx.scene.effect.BlendMode;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import javafx.stage.Stage;
|
||||
import reader.CRISMPDSImageNextGen;
|
||||
import util.JCATConfig;
|
||||
import util.JCATLog;
|
||||
import util.JCATMessageWindow;
|
||||
|
||||
public class MTRDRBrowseProducts extends JCATCalls {
|
||||
|
||||
private ComboBox<String> bpChoices;
|
||||
private int red_;
|
||||
private int grn_;
|
||||
private int blu_;
|
||||
private int toggle = 0;
|
||||
|
||||
public boolean create(String imgfile, String basefile) throws IOException {
|
||||
|
||||
///////////////////////////////////////
|
||||
// Establishes rootDir as the JCAT folder in home directory
|
||||
///////////////////////////////////////
|
||||
File rootDir = new File(System.getProperty("user.home"), "JCAT");
|
||||
if (!rootDir.isDirectory()) {
|
||||
rootDir.mkdirs();
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Instantiates CRISM based on 's', 'l' or 'j' data ID as CRISMPDSImageNextGen
|
||||
// or TRDR
|
||||
// If TRDR, ADRVSLibrary is created for potential volcano scan corrections
|
||||
// adrNames becomes a list of correct bin code and wavelength filter
|
||||
// created BEFORE the TRDR file
|
||||
// adrIDList and adrIDItems contain the ID's of the applicable ADR's
|
||||
// correctADRfiles holds the most recent of each ADR ID to
|
||||
// be called during volcano scan implementation
|
||||
///////////////////////////////////////
|
||||
basefile = FilenameUtils.getBaseName(basefile);
|
||||
|
||||
if (basefile.substring(20, 21).toLowerCase().equals("j"))
|
||||
CRISM = new CRISMPDSImageNextGen(imgfile);
|
||||
|
||||
if (!CRISM.validImage)
|
||||
return false;
|
||||
|
||||
int height = (int) CRISM.getHeight(), width = (int) CRISM.getWidth();
|
||||
int startRow = height / 2, startCol = width / 2;
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Creates a menu bar with multiple menus
|
||||
// Toggle groups/Radio Menu Items ensure only one if selected at a time
|
||||
// Disables the zoom menus that will cause sizing issues
|
||||
// Check Menu Item for subset/photometric can be selected/de-selected anytime
|
||||
///////////////////////////////////////////////////
|
||||
if ((height * 0.5) < 300 || (width * 0.5) < 300) {
|
||||
zoom50.setDisable(true);
|
||||
}
|
||||
zoom50.setToggleGroup(zoomTG);
|
||||
if ((height * 0.75) < 300 || (width * 0.75) < 300) {
|
||||
zoom75.setDisable(true);
|
||||
}
|
||||
zoom75.setToggleGroup(zoomTG);
|
||||
zoom100.setToggleGroup(zoomTG);
|
||||
zoom100.setSelected(true);
|
||||
zoom125.setToggleGroup(zoomTG);
|
||||
zoom150.setToggleGroup(zoomTG);
|
||||
zoom200.setToggleGroup(zoomTG);
|
||||
|
||||
linStretch.setToggleGroup(contrastTG);
|
||||
per1Stretch.setToggleGroup(contrastTG);
|
||||
per1Stretch.setSelected(true);
|
||||
per2Stretch.setToggleGroup(contrastTG);
|
||||
perCStretch.setToggleGroup(contrastTG);
|
||||
contrast.getItems().addAll(linStretch, per1Stretch, per2Stretch, perCStretch, subStretch);
|
||||
|
||||
fileMenu.getItems().addAll(expandImg, saveImg, new SeparatorMenuItem(), close);
|
||||
zoomMenu.getItems().addAll(zoom50, zoom75, zoom100, zoom125, zoom150, zoom200);
|
||||
controlsMenu.getItems().addAll(contrast);
|
||||
|
||||
mbar.getMenus().addAll(fileMenu, zoomMenu, controlsMenu);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Creates the layout for the image frame:
|
||||
// borderTB: top, bottom - bottom will be line chart
|
||||
// borderLR: left, right - R will hold slider, coordinates, update RGB button
|
||||
// border TL: top left (left side), top left (right side) - houses two images
|
||||
// Housed in a scroll pane to allow users to move about the window
|
||||
/////////////////////////////////////////
|
||||
BorderPane borderTB = new BorderPane(), borderLR = new BorderPane(),
|
||||
borderTL = new BorderPane();
|
||||
GridPane controls = new GridPane();
|
||||
ScrollPane mainSP = new ScrollPane();
|
||||
|
||||
VBox root2 = new VBox();
|
||||
root2.getChildren().addAll(mbar, mainSP);
|
||||
|
||||
controls.setPadding(new Insets(10, 10, 10, 10));
|
||||
controls.setVgap(5);
|
||||
controls.setHgap(30);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Creates a canvas for cross-hair, rectangle and region of interest will be
|
||||
// drawn on
|
||||
//////////////////////////////////////////
|
||||
Canvas canvas = new Canvas(width, height);
|
||||
|
||||
bImg = percentileStretch(CRISM.getQuickMonoImage(0), 1);
|
||||
image = SwingFXUtils.toFXImage(bImg, null);
|
||||
|
||||
ImageView iv = new ImageView(image), iv2 = new ImageView(image);
|
||||
ImageView iv3 = new ImageView(), iv4 = new ImageView();
|
||||
Group blend = new Group(iv, iv3), blend2 = new Group(iv2, iv4);
|
||||
Group finalImg = new Group(blend), finalImg2 = new Group(blend2);
|
||||
|
||||
ScrollPane sp = new ScrollPane(finalImg), sp2 = new ScrollPane(finalImg2);
|
||||
sp.setPrefSize(300, 300);
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Blends the image plus user reference (cross-hair, etc.) with a black
|
||||
// rectangle to create final display
|
||||
//////////////////////////////////////////////////////////
|
||||
img = canvas.snapshot(null, null);
|
||||
iv3.setImage(img);
|
||||
iv4.setImage(img);
|
||||
Rectangle black = new Rectangle(width, height);
|
||||
|
||||
iv3.setBlendMode(BlendMode.DIFFERENCE);
|
||||
black.setFill(Color.BLACK);
|
||||
finalImg.setBlendMode(BlendMode.DIFFERENCE);
|
||||
sp.setContent(finalImg);
|
||||
|
||||
iv4.setBlendMode(BlendMode.DIFFERENCE);
|
||||
black.setFill(Color.BLACK);
|
||||
finalImg2.setBlendMode(BlendMode.DIFFERENCE);
|
||||
sp2.setContent(finalImg2);
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Creates another image view for the shrunken second image
|
||||
// Preserves the width-height ratio, but makes the larger quantity = 300
|
||||
// Does some math to figure what range-of-view rectangle height&width should be
|
||||
// and how the scroll bars will line up with the image
|
||||
/////////////////////////////////////////////
|
||||
ImageView imgZoom = new ImageView(image);
|
||||
imgZoom.setPreserveRatio(true);
|
||||
imgZoom.setFitHeight(300);
|
||||
imgZoom.setFitWidth(300);
|
||||
|
||||
double ratio = (double) 300 / (Math.max(height, width));
|
||||
double adjHeight = height * ratio, adjWidth = width * ratio;
|
||||
double rectHeight = 300 * ratio, rectWidth = 300 * ratio;
|
||||
|
||||
sp.setHmax(adjWidth - rectWidth);
|
||||
sp.setVmax(adjHeight - rectHeight);
|
||||
sp.setHvalue(sp.getHmax() / 2);
|
||||
sp.setVvalue(sp.getVmax() / 2);
|
||||
|
||||
Rectangle rect = new Rectangle(300 + sp.getHvalue(), sp.getVvalue(), rectWidth, rectHeight);
|
||||
rect.setStroke(Color.BLACK);
|
||||
rect.setFill(null);
|
||||
rect.setStrokeWidth(3);
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Creates labels, sliders, and value labels for RGB sliders
|
||||
// Sets wavelengths as values on slider, creates tick marks
|
||||
///////////////////////////////////////////////////////////
|
||||
Label labelBP = new Label("Browse Product:");
|
||||
|
||||
ObservableList<String> options =
|
||||
FXCollections.observableArrayList("TRU", "VNA", "FEM", "FM2", "TAN", "IRA", "FAL", "MAF",
|
||||
"HYD", "PHY", "PFM", "PAL", "HYS", "ICE", "IC2", "CHL", "CAR", "CR2");
|
||||
|
||||
bpChoices = new ComboBox<String>(options);
|
||||
File userBP = new File(rootDir, "userBP_MTRDR.txt");
|
||||
List<String> userName = new ArrayList<String>();
|
||||
if (userBP.exists()) {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO,
|
||||
"Adding user-created browse products to menu");
|
||||
Vector<String[]> list = getRecentBP();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
String[] BP = list.get(i);
|
||||
String name = BP[0];
|
||||
userName.add(name);
|
||||
}
|
||||
}
|
||||
bpChoices.getItems().addAll(userName);
|
||||
|
||||
Button okBtn = new Button("Set RGB");
|
||||
ObservableList<String> items = FXCollections.observableArrayList("R770", "RBR", "BD530_2",
|
||||
"SH600_2", "SH770", "BD640_2", "BD860_2", "BD920_2", "RPEAK1", "BDI1000VIS", "R440", "IRR1",
|
||||
"BDI1000IR", "OLINDEX3", "R1330", "BD1300", "LCPINDEX2", "HCPINDEX2", "VAR", "ISLOPE1",
|
||||
"BD1400", "BD1435", "BD1500_2", "ICER1_2", "BD1750_2", "BD1900_2", "BD1900R2", "BDI2000",
|
||||
"BD2100_2", "BD2165", "BD2190", "MIN2200", "BD2210_2", "D2200", "BD2230", "BD2250",
|
||||
"MIN2250", "BD2265", "BD2290", "D2300", "BD2355", "SINDEX2", "ICER2_2", "MIN2295_2480",
|
||||
"MIN2345_2537", "BD2500_2", "BD3000", "BD3100", "BD3200", "BD3400_2", "CINDEX2", "BD2600",
|
||||
"IRR2", "IRR3", "R530", "R600", "R1080", "R1506", "R2529", "R3920");
|
||||
|
||||
ComboBox<String> red = new ComboBox<>(items);
|
||||
ComboBox<String> green = new ComboBox<>(items);
|
||||
ComboBox<String> blue = new ComboBox<>(items);
|
||||
|
||||
Button updateBtn = new Button("Update Image");
|
||||
Button addBtn = new Button("Add new browse product");
|
||||
Button saveBtn = new Button("Save new browse product");
|
||||
Label subLabel = new Label();
|
||||
|
||||
Label selectedBP = new Label(bpChoices.getValue());
|
||||
selectedBP.setText("Current: None");
|
||||
////////////////////////////////////////////////////
|
||||
// Creates coordinate label
|
||||
// Displays start row and column at center of image,
|
||||
// longitude and latitude
|
||||
/////////////////////////////////////////////////////
|
||||
longitude = CRISM.getLon(startRow, startCol);
|
||||
latitude = CRISM.getLat(startRow, startCol);
|
||||
Label crdValue =
|
||||
new Label("Data (row, col): (" + startRow + ", " + startCol + ")" + ", Latitude: "
|
||||
+ String.format("%.4f", latitude) + ", Longitude: " + String.format("%.4f", longitude));
|
||||
crdValue.setMinWidth(325);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Sets location of slider, coordinate objects in top-right section of grid pane
|
||||
// Sets the content of the different border/scroll panes
|
||||
////////////////////////////////////////////////////
|
||||
GridPane.setConstraints(crdValue, 1, 3);
|
||||
GridPane.setConstraints(updateBtn, 2, 3);
|
||||
GridPane.setConstraints(addBtn, 2, 4);
|
||||
GridPane.setConstraints(saveBtn, 2, 5);
|
||||
GridPane.setConstraints(subLabel, 2, 6);
|
||||
|
||||
GridPane.setConstraints(labelBP, 0, 2);
|
||||
GridPane.setConstraints(bpChoices, 1, 2);
|
||||
|
||||
GridPane.setConstraints(selectedBP, 1, 4);
|
||||
|
||||
controls.getChildren().addAll(labelBP, bpChoices, selectedBP, crdValue, updateBtn, addBtn,
|
||||
saveBtn, subLabel);
|
||||
|
||||
borderTL.setLeft(sp);
|
||||
borderTL.setRight(imgZoom);
|
||||
borderLR.setLeft(borderTL);
|
||||
borderLR.getChildren().add(rect);
|
||||
borderLR.setRight(controls);
|
||||
borderTB.setTop(borderLR);
|
||||
mainSP.setContent(borderTB);
|
||||
mainSP.setFitToHeight(true);
|
||||
mainSP.setFitToWidth(true);
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Creates the scene and stage for the second window to be shown
|
||||
// Creates the scene for the expanded image, can close and reopen
|
||||
//////////////////////////////////////////////
|
||||
Scene scene2 = new Scene(root2);
|
||||
Stage stage2 = new Stage();
|
||||
stage2.setTitle(basefile);
|
||||
stage2.setScene(scene2);
|
||||
stage2.show();
|
||||
|
||||
Scene scene3 = new Scene(sp2, width, height);
|
||||
Stage stage3 = new Stage();
|
||||
stage3.setTitle(basefile);
|
||||
stage3.setScene(scene3);
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Gets the x, y, w, h of visible area in scroll pane
|
||||
// This is used during a subset stretch
|
||||
// NOTE: Must be run AFTER scene is shown for viewportBounds to exist
|
||||
//////////////////////////////////////////////
|
||||
double hmin = sp.getHmin(), hmax = sp.getHmax(), hvalue = sp.getHvalue();
|
||||
double contentWidth = iv.getLayoutBounds().getWidth() * (1 / scaleFactor);
|
||||
visW = (int) (sp.getViewportBounds().getWidth() * (1 / scaleFactor));
|
||||
visX = (int) (Math.max(0, contentWidth - visW) * (hvalue - hmin) / (hmax - hmin));
|
||||
|
||||
double vmin = sp.getVmin(), vmax = sp.getVmax(), vvalue = sp.getVvalue();
|
||||
double contentHeight = iv.getLayoutBounds().getHeight() * (1 / scaleFactor);
|
||||
visH = (int) (sp.getViewportBounds().getHeight() * (1 / scaleFactor));
|
||||
visY = (int) (Math.max(0, contentHeight - visH) * (vvalue - vmin) / (vmax - vmin));
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Opens a third window and expands image to its full size
|
||||
///////////////////////////////////////////////
|
||||
expandImg.setOnAction(event -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Expanding Image");
|
||||
stage3.show();
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Saves the currently shown image, with RGB values in filename
|
||||
//////////////////////////////////////////////////
|
||||
saveImg.setOnAction(event -> {
|
||||
|
||||
TextInputDialog input = new TextInputDialog();
|
||||
input.setTitle("File Name");
|
||||
input.setContentText("Set filename: ");
|
||||
String result = tidy(input.showAndWait());
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO,
|
||||
"Saving shown image as: " + result + ".png");
|
||||
|
||||
File f = new File(result + ".png");
|
||||
BufferedImage biSave = SwingFXUtils.fromFXImage(iv.getImage(), null);
|
||||
try {
|
||||
ImageIO.write(biSave, "PNG", f);
|
||||
} catch (IOException e1) {
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING, "Error saving image");
|
||||
e1.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Adjusts zoom of image, range-of-view rectangle size and sets scroll pane to
|
||||
// the same position
|
||||
//////////////////////////////////////////////////////
|
||||
zoomTG.selectedToggleProperty().addListener((obs, old_toggle, new_toggle) -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "Adjusting Zoom to selected level");
|
||||
scaleFactor = (zoom50.isSelected()) ? 0.5 : scaleFactor;
|
||||
scaleFactor = (zoom75.isSelected()) ? 0.75 : scaleFactor;
|
||||
scaleFactor = (zoom100.isSelected()) ? 1 : scaleFactor;
|
||||
scaleFactor = (zoom125.isSelected()) ? 1.25 : scaleFactor;
|
||||
scaleFactor = (zoom150.isSelected()) ? 1.5 : scaleFactor;
|
||||
scaleFactor = (zoom200.isSelected()) ? 2 : scaleFactor;
|
||||
int hVal = (int) sp.getHvalue();
|
||||
int vVal = (int) sp.getVvalue();
|
||||
int hMax = (int) sp.getHmax();
|
||||
int vMax = (int) sp.getVmax();
|
||||
iv.setPreserveRatio(true);
|
||||
iv.setFitHeight(height * scaleFactor);
|
||||
iv.setFitWidth(width * scaleFactor);
|
||||
iv3.setPreserveRatio(true);
|
||||
iv3.setFitHeight(height * scaleFactor);
|
||||
iv3.setFitWidth(width * scaleFactor);
|
||||
rect.setHeight(rectHeight * (1 / scaleFactor));
|
||||
rect.setWidth(rectWidth * (1 / scaleFactor));
|
||||
sp.setHmax(adjWidth - rect.getWidth());
|
||||
sp.setVmax(adjHeight - rect.getHeight());
|
||||
sp.setHvalue(hVal * (sp.getHmax() / hMax));
|
||||
sp.setVvalue(vVal * (sp.getVmax() / vMax));
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Sets the rectangle to correct position after scroll bars have been moved
|
||||
// Whenever scale or scroll bars change, the visible bounds adjust accordingly
|
||||
// This is important for the subset image stretches
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ChangeListener<Object> changeListener = new ChangeListener<Object>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Object> observable, Object oldValue,
|
||||
Object newValue) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method changed in launch class");
|
||||
double hmin = sp.getHmin(), hmax = sp.getHmax(), hvalue = sp.getHvalue();
|
||||
double contentWidth = iv.getLayoutBounds().getWidth() * (1 / scaleFactor);
|
||||
visW = (int) (sp.getViewportBounds().getWidth() * (1 / scaleFactor));
|
||||
visX = (int) (Math.max(0, contentWidth - visW) * (hvalue - hmin) / (hmax - hmin));
|
||||
rect.setX(300 + hvalue);
|
||||
|
||||
double vmin = sp.getVmin(), vmax = sp.getVmax(), vvalue = sp.getVvalue();
|
||||
double contentHeight = iv.getLayoutBounds().getHeight() * (1 / scaleFactor);
|
||||
visH = (int) (sp.getViewportBounds().getHeight() * (1 / scaleFactor));
|
||||
visY = (int) (Math.max(0, contentHeight - visH) * (vvalue - vmin) / (vmax - vmin));
|
||||
rect.setY(vvalue);
|
||||
}
|
||||
};
|
||||
sp.viewportBoundsProperty().addListener(changeListener);
|
||||
sp.hvalueProperty().addListener(changeListener);
|
||||
sp.vvalueProperty().addListener(changeListener);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Displays new row/col & lat/lon location whenever mouse moves on image
|
||||
// Row/col are 1:1 ratio with image, with (0, 0) at top left of both
|
||||
////////////////////////////////////////////////////
|
||||
finalImg.setOnMouseMoved(e -> {
|
||||
int newRow = (int) (e.getY() * (1 / scaleFactor));
|
||||
int newCol = (int) (e.getX() * (1 / scaleFactor));
|
||||
double longitude = CRISM.getLon(newRow, newCol);
|
||||
double latitude = CRISM.getLat(newRow, newCol);
|
||||
crdValue.setText("Data (row, col): (" + newRow + ", " + newCol + ")" + ", Latitude: "
|
||||
+ String.format("%.4f", latitude) + ", Longitude: " + String.format("%.4f", longitude)
|
||||
+ "\nRed: " + CRISM.getPCFloatValue(newRow, newCol, red_) + " Green: "
|
||||
+ CRISM.getPCFloatValue(newRow, newCol, grn_) + " Blue: "
|
||||
+ CRISM.getPCFloatValue(newRow, newCol, blu_));
|
||||
});
|
||||
|
||||
finalImg2.setOnMouseMoved(e -> {
|
||||
int newRow = (int) (e.getY());
|
||||
int newCol = (int) (e.getX());
|
||||
double longitude = CRISM.getLon(newRow, newCol);
|
||||
double latitude = CRISM.getLat(newRow, newCol);
|
||||
crdValue.setText("Data (row, col): (" + newRow + ", " + newCol + ")" + "Latitude: "
|
||||
+ String.format("%.4f", latitude) + ", Longitude: " + String.format("%.4f", longitude));
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Gets the current chart, removes the RGB values and inputs the current values
|
||||
// Checks what is selected in contrast menu
|
||||
// Applies stretches with new RGB values
|
||||
// Checks whether subset stretch is selected,
|
||||
// Else use entire image for stretch
|
||||
///////////////////////////////////////////////////////////
|
||||
updateBtn.setOnAction(e -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Updating browse product");
|
||||
|
||||
String redString;
|
||||
String grnString;
|
||||
String bluString;
|
||||
if (toggle == 0) {
|
||||
int bpNum = bpChoices.getItems().indexOf(bpChoices.getValue());
|
||||
|
||||
String currentBP = bpChoices.getItems().get(bpNum);
|
||||
if (bpNum == 0) {
|
||||
// TRU
|
||||
red_ = CRISM.findBandNumber("R600");
|
||||
grn_ = CRISM.findBandNumber("R530");
|
||||
blu_ = CRISM.findBandNumber("R440");
|
||||
|
||||
} else if (bpNum == 1) {
|
||||
// VNA
|
||||
red_ = CRISM.findBandNumber("R770");
|
||||
grn_ = red_;
|
||||
blu_ = red_;
|
||||
|
||||
} else if (bpNum == 2) {
|
||||
// FEM
|
||||
red_ = CRISM.findBandNumber("BD530_2");
|
||||
grn_ = CRISM.findBandNumber("SH600_2");
|
||||
blu_ = CRISM.findBandNumber("BDI1000VIS");
|
||||
|
||||
} else if (bpNum == 3) {
|
||||
// FM2
|
||||
red_ = CRISM.findBandNumber("BD530_2");
|
||||
grn_ = CRISM.findBandNumber("BD920_2");
|
||||
blu_ = CRISM.findBandNumber("BDI1000VIS");
|
||||
|
||||
} else if (bpNum == 4) {
|
||||
// TAN
|
||||
red_ = CRISM.findBandNumber("R2529");
|
||||
grn_ = CRISM.findBandNumber("R1330");
|
||||
blu_ = CRISM.findBandNumber("R770");
|
||||
|
||||
} else if (bpNum == 5) {
|
||||
// IRA
|
||||
red_ = CRISM.findBandNumber("R1330");
|
||||
grn_ = red_;
|
||||
blu_ = red_;
|
||||
|
||||
} else if (bpNum == 6) {
|
||||
// FAL
|
||||
red_ = CRISM.findBandNumber("R2529");
|
||||
grn_ = CRISM.findBandNumber("R1506");
|
||||
blu_ = CRISM.findBandNumber("R1080");
|
||||
|
||||
} else if (bpNum == 7) {
|
||||
// MAF
|
||||
red_ = CRISM.findBandNumber("OLINDEX3");
|
||||
grn_ = CRISM.findBandNumber("LCPINDEX2");
|
||||
blu_ = CRISM.findBandNumber("HCPINDEX2");
|
||||
|
||||
} else if (bpNum == 8) {
|
||||
// HYD
|
||||
red_ = CRISM.findBandNumber("SINDEX2");
|
||||
grn_ = CRISM.findBandNumber("BD2100_2");
|
||||
blu_ = CRISM.findBandNumber("BD1900_2");
|
||||
|
||||
} else if (bpNum == 9) {
|
||||
// PHY
|
||||
red_ = CRISM.findBandNumber("D2300");
|
||||
grn_ = CRISM.findBandNumber("D2200");
|
||||
blu_ = CRISM.findBandNumber("BD1900r2");
|
||||
|
||||
} else if (bpNum == 10) {
|
||||
// PFM
|
||||
red_ = CRISM.findBandNumber("BD2355");
|
||||
grn_ = CRISM.findBandNumber("D2300");
|
||||
blu_ = CRISM.findBandNumber("BD2290");
|
||||
|
||||
} else if (bpNum == 11) {
|
||||
// PAL
|
||||
red_ = CRISM.findBandNumber("BD2210_2");
|
||||
grn_ = CRISM.findBandNumber("BD2190");
|
||||
blu_ = CRISM.findBandNumber("BD2165");
|
||||
|
||||
} else if (bpNum == 12) {
|
||||
// HYS
|
||||
red_ = CRISM.findBandNumber("MIN2250");
|
||||
grn_ = CRISM.findBandNumber("BD2250");
|
||||
blu_ = CRISM.findBandNumber("BD1900r2");
|
||||
|
||||
} else if (bpNum == 13) {
|
||||
// ICE
|
||||
red_ = CRISM.findBandNumber("BD1900_2");
|
||||
grn_ = CRISM.findBandNumber("BD1500_2");
|
||||
blu_ = CRISM.findBandNumber("BD1435");
|
||||
|
||||
} else if (bpNum == 14) {
|
||||
// IC2
|
||||
red_ = CRISM.findBandNumber("R3920");
|
||||
grn_ = CRISM.findBandNumber("BD1500_2");
|
||||
blu_ = CRISM.findBandNumber("BD1435");
|
||||
|
||||
} else if (bpNum == 15) {
|
||||
// CHL
|
||||
red_ = CRISM.findBandNumber("ISLOPE1");
|
||||
grn_ = CRISM.findBandNumber("BD3000");
|
||||
blu_ = CRISM.findBandNumber("IRR2");
|
||||
|
||||
} else if (bpNum == 16) {
|
||||
// CAR
|
||||
red_ = CRISM.findBandNumber("D2300");
|
||||
grn_ = CRISM.findBandNumber("BD2500_2");
|
||||
blu_ = CRISM.findBandNumber("BD1900_2");
|
||||
|
||||
} else if (bpNum == 17) {
|
||||
// CR2
|
||||
red_ = CRISM.findBandNumber("MIN2295_2480");
|
||||
grn_ = CRISM.findBandNumber("MIN2345_2537");
|
||||
blu_ = CRISM.findBandNumber("CINDEX2");
|
||||
} else {
|
||||
int index = bpNum - 18;
|
||||
Vector<String[]> list = getRecentBP();
|
||||
String[] BP = list.get(index);
|
||||
currentBP = BP[0];
|
||||
red_ = CRISM.findBandNumber(items.get(Integer.parseInt(BP[1])));
|
||||
grn_ = CRISM.findBandNumber(items.get(Integer.parseInt(BP[2])));
|
||||
blu_ = CRISM.findBandNumber(items.get(Integer.parseInt(BP[3])));
|
||||
}
|
||||
|
||||
selectedBP.setText("Current: " + currentBP);
|
||||
redString = currentBP;
|
||||
grnString = currentBP;
|
||||
bluString = currentBP;
|
||||
} else {
|
||||
selectedBP.setText(
|
||||
"Current: R " + red.getValue() + " G " + green.getValue() + " B " + blue.getValue());
|
||||
redString = red.getValue();
|
||||
grnString = green.getValue();
|
||||
bluString = blue.getValue();
|
||||
}
|
||||
|
||||
if (red_ >= 0 && grn_ >= 0 && blu_ >= 0) {
|
||||
applyBP(subLabel, iv, iv2, imgZoom);
|
||||
} else {
|
||||
if (red_ < 0)
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Missing Red band for: " + redString);
|
||||
if (grn_ < 0)
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Missing Green band for: " + grnString);
|
||||
if (blu_ < 0)
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Missing Blue band for: " + bluString);
|
||||
}
|
||||
toggle = 0;
|
||||
});
|
||||
|
||||
GridPane bpGrid = new GridPane();
|
||||
GridPane.setConstraints(red, 1, 1);
|
||||
GridPane.setConstraints(green, 2, 1);
|
||||
GridPane.setConstraints(blue, 3, 1);
|
||||
GridPane.setConstraints(okBtn, 4, 1);
|
||||
bpGrid.getChildren().addAll(red, green, blue, okBtn);
|
||||
|
||||
HBox newRoot = new HBox();
|
||||
newRoot.getChildren().add(bpGrid);
|
||||
Scene scene4 = new Scene(newRoot);
|
||||
Stage stage4 = new Stage();
|
||||
stage4.setTitle("Choose RGB for New Browse Product");
|
||||
stage4.setScene(scene4);
|
||||
|
||||
addBtn.setOnAction(e -> {
|
||||
stage4.show();
|
||||
});
|
||||
|
||||
okBtn.setOnAction(event -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Adjusting RGB for new browse product");
|
||||
String R = red.getValue();
|
||||
String G = green.getValue();
|
||||
String B = blue.getValue();
|
||||
red_ = CRISM.findBandNumber(R);
|
||||
grn_ = CRISM.findBandNumber(G);
|
||||
blu_ = CRISM.findBandNumber(B);
|
||||
|
||||
toggle = 1;
|
||||
|
||||
stage4.close();
|
||||
});
|
||||
|
||||
saveBtn.setOnAction(e -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Saving new browse product");
|
||||
|
||||
TextInputDialog input = new TextInputDialog();
|
||||
input.setTitle("New Browse Product");
|
||||
input.setContentText("Name new browse product: ");
|
||||
String result = tidy(input.showAndWait());
|
||||
|
||||
String[] bp = {result, Integer.toString(red.getItems().indexOf(red.getValue())),
|
||||
Integer.toString(green.getItems().indexOf(green.getValue())),
|
||||
Integer.toString(blue.getItems().indexOf(blue.getValue()))};
|
||||
saveNewBP(bp);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void applyBP(Label subLabel, ImageView iv, ImageView iv2, ImageView imgZoom) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering applyBP method");
|
||||
|
||||
BufferedImage newBI = CRISM.getQuickColorImage(red_, grn_, blu_);
|
||||
|
||||
bImg = stretchImage(newBI);
|
||||
if (bImg != null && subStretch.isSelected())
|
||||
subLabel
|
||||
.setText("Row: " + visX + "-" + (visX + visW) + ", Col: " + visY + "-" + (visY + visH));
|
||||
else
|
||||
subLabel.setText(null);
|
||||
|
||||
/*-
|
||||
List<Double> stretchValues = null;
|
||||
if (perCStretch.isSelected()) {
|
||||
TextInputDialog input = new TextInputDialog();
|
||||
input.setTitle("Percentile Stretch");
|
||||
input.setContentText("Input Percentile (Value): ");
|
||||
Optional<String> result = input.showAndWait();
|
||||
double stretch = Double.parseDouble(tidy(result));
|
||||
if (result.isPresent()) {
|
||||
if (subStretch.isSelected()) {
|
||||
stretchValues = ImageUtils.getStretchValues(newBI.getSubimage(visX, visY, visW, visH), STRETCH.LINEAR, stretch);
|
||||
bImg = percentileSubStretch(newBI, stretchValues);
|
||||
subLabel.setText("Row: " + visX + "-" + (visX + visW) + ", Col: " + visY + "-" + (visY + visH));
|
||||
} else {
|
||||
bImg = percentileStretch(newBI, stretch);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (subStretch.isSelected()) {
|
||||
if (linStretch.isSelected()) {
|
||||
|
||||
stretchValues = ImageUtils.getStretchValues(newBI.getSubimage(visX, visY, visW, visH), STRETCH.LINEAR, 0);
|
||||
bImg = linSubStretch(newBI, stretchValues);
|
||||
} else if (per1Stretch.isSelected()) {
|
||||
|
||||
stretchValues = ImageUtils.getStretchValues(newBI.getSubimage(visX, visY, visW, visH), STRETCH.LINEAR, 1);
|
||||
bImg = percentileSubStretch(newBI, stretchValues);
|
||||
} else if (per2Stretch.isSelected()) {
|
||||
|
||||
stretchValues = ImageUtils.getStretchValues(newBI.getSubimage(visX, visY, visW, visH), STRETCH.LINEAR, 2);
|
||||
bImg = percentileSubStretch(newBI, stretchValues);
|
||||
}
|
||||
subLabel.setText("Row: " + visX + "-" + (visX + visW) + ", Col: " + visY + "-" + (visY + visH));
|
||||
} else {
|
||||
bImg = (linStretch.isSelected()) ? linearStretch(newBI) : bImg;
|
||||
bImg = (per1Stretch.isSelected()) ? percentileStretch(newBI, 1) : bImg;
|
||||
bImg = (per2Stretch.isSelected()) ? percentileStretch(newBI, 2) : bImg;
|
||||
subLabel.setText(null);
|
||||
}
|
||||
}
|
||||
*/
|
||||
image = SwingFXUtils.toFXImage(bImg, null);
|
||||
iv.setImage(image);
|
||||
iv2.setImage(image);
|
||||
imgZoom.setImage(image);
|
||||
}
|
||||
|
||||
public void saveNewBP(String[] bp) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method saveNewBP");
|
||||
Vector<String[]> lines = getRecentBP();
|
||||
try {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Adding name to userBP: " + bp[0]);
|
||||
String path =
|
||||
JCATConfig.getInstance().getLocalArchive() + File.separator + "userBP_MTRDR.txt";
|
||||
File f = new File(path);
|
||||
PrintWriter out;
|
||||
out = new PrintWriter(new FileWriter(f));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(bp[0] + " " + bp[1] + " " + bp[2] + " " + bp[3]);
|
||||
out.println(sb);
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
String[] current = lines.elementAt(i);
|
||||
String s = null;
|
||||
if (!Arrays.equals(bp, current))
|
||||
s = convertArraytoString(current, ",");
|
||||
out.print(s + "\n");
|
||||
}
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING, "Error adding browse product");
|
||||
JCATMessageWindow.show(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Vector<String[]> getRecentBP() {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method getRecentBP");
|
||||
Vector<String[]> lines = new Vector<String[]>();
|
||||
try {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Displaying recent BP");
|
||||
String path =
|
||||
JCATConfig.getInstance().getLocalArchive() + File.separator + "userBP_MTRDR.txt";
|
||||
File f = new File(path);
|
||||
if (f.exists()) {
|
||||
BufferedReader in = new BufferedReader(new FileReader(f));
|
||||
String line = null;
|
||||
while ((line = in.readLine()) != null) {
|
||||
String strArray[] = line.split(" ");
|
||||
lines.add(strArray);
|
||||
}
|
||||
in.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING,
|
||||
"Error retriving recent browse products.");
|
||||
JCATMessageWindow.show(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
public String convertArraytoString(String[] array, String delimiter) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String str : array)
|
||||
sb.append(str).append(delimiter);
|
||||
String s = sb.toString().replaceAll(",", " ");
|
||||
return s.substring(0, sb.length() - 1);
|
||||
}
|
||||
}
|
||||
470
src/main/java/javafx/MTRDRSummaryParameters.java
Normal file
470
src/main/java/javafx/MTRDRSummaryParameters.java
Normal file
@@ -0,0 +1,470 @@
|
||||
package javafx;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.embed.swing.SwingFXUtils;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Menu;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.SeparatorMenuItem;
|
||||
import javafx.scene.control.TextInputDialog;
|
||||
import javafx.scene.effect.BlendMode;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import javafx.stage.Stage;
|
||||
import reader.CRISMPDSImageNextGen;
|
||||
import util.JCATLog;
|
||||
|
||||
public class MTRDRSummaryParameters extends JCATCalls {
|
||||
|
||||
private int bandNum;
|
||||
private ComboBox<String> summaryParameters;
|
||||
private int spCode = 1;
|
||||
|
||||
protected float[][][] mappedData_;
|
||||
private float[][] currentSP;
|
||||
|
||||
public boolean create(String imgfile, String basefile) throws IOException {
|
||||
|
||||
String baseF = basefile;
|
||||
///////////////////////////////////////
|
||||
// Establishes rootDir as the JCAT folder in home directory
|
||||
///////////////////////////////////////
|
||||
File rootDir = new File(System.getProperty("user.home"), "JCAT");
|
||||
if (!rootDir.isDirectory()) {
|
||||
rootDir.mkdirs();
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Instantiates CRISM based on 's', 'l' or 'j' data ID as CRISMPDSImageNextGen
|
||||
///////////////////////////////////////
|
||||
basefile = FilenameUtils.getBaseName(basefile);
|
||||
if (basefile.substring(20, 21).toLowerCase().equals("j")) {
|
||||
|
||||
CRISM = new CRISMPDSImageNextGen(imgfile);
|
||||
}
|
||||
|
||||
if (!CRISM.validImage)
|
||||
return false;
|
||||
|
||||
int height = (int) CRISM.getHeight(), width = (int) CRISM.getWidth();
|
||||
int startRow = height / 2, startCol = width / 2;
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Creates a menu bar with multiple menus
|
||||
// Toggle groups/Radio Menu Items ensure only one if selected at a time
|
||||
// Disables the zoom menus that will cause sizing issues
|
||||
// Check Menu Item for subset/photometric can be selected/de-selected anytime
|
||||
///////////////////////////////////////////////////
|
||||
if ((height * 0.5) < 300 || (width * 0.5) < 300) {
|
||||
zoom50.setDisable(true);
|
||||
}
|
||||
zoom50.setToggleGroup(zoomTG);
|
||||
if ((height * 0.75) < 300 || (width * 0.75) < 300) {
|
||||
zoom75.setDisable(true);
|
||||
}
|
||||
zoom75.setToggleGroup(zoomTG);
|
||||
zoom100.setToggleGroup(zoomTG);
|
||||
zoom100.setSelected(true);
|
||||
zoom125.setToggleGroup(zoomTG);
|
||||
zoom150.setToggleGroup(zoomTG);
|
||||
zoom200.setToggleGroup(zoomTG);
|
||||
|
||||
linStretch.setToggleGroup(contrastTG);
|
||||
per1Stretch.setToggleGroup(contrastTG);
|
||||
per1Stretch.setSelected(true);
|
||||
per2Stretch.setToggleGroup(contrastTG);
|
||||
perCStretch.setToggleGroup(contrastTG);
|
||||
contrast.getItems().addAll(linStretch, per1Stretch, per2Stretch, perCStretch, subStretch);
|
||||
|
||||
fileMenu.getItems().addAll(expandImg, saveImg, new SeparatorMenuItem(), close);
|
||||
zoomMenu.getItems().addAll(zoom50, zoom75, zoom100, zoom125, zoom150, zoom200);
|
||||
controlsMenu.getItems().addAll(contrast);
|
||||
|
||||
Menu browseProducts = new Menu("View Browse Products");
|
||||
controlsMenu.getItems().add(browseProducts);
|
||||
browseProducts.setOnAction(e -> {
|
||||
try {
|
||||
new MTRDRBrowseProducts().create(imgfile, baseF);
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
mbar.getMenus().addAll(fileMenu, zoomMenu, controlsMenu);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Creates the layout for the image frame:
|
||||
// borderTB: top, bottom - bottom will be line chart
|
||||
// borderLR: left, right - R will hold slider, coordinates, update RGB button
|
||||
// border TL: top left (left side), top left (right side) - houses two images
|
||||
// Housed in a scroll pane to allow users to move about the window
|
||||
/////////////////////////////////////////
|
||||
BorderPane borderTB = new BorderPane(), borderLR = new BorderPane(),
|
||||
borderTL = new BorderPane();
|
||||
GridPane controls = new GridPane();
|
||||
ScrollPane mainSP = new ScrollPane();
|
||||
|
||||
VBox root2 = new VBox();
|
||||
root2.getChildren().addAll(mbar, mainSP);
|
||||
|
||||
controls.setPadding(new Insets(10, 10, 10, 10));
|
||||
controls.setVgap(5);
|
||||
controls.setHgap(30);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Creates a canvas for cross-hair, rectangle and region of interest will be
|
||||
// drawn on
|
||||
//////////////////////////////////////////
|
||||
Canvas canvas = new Canvas(width, height);
|
||||
|
||||
bImg = percentileStretch(CRISM.getQuickMonoImage(0), 1);
|
||||
|
||||
image = SwingFXUtils.toFXImage(bImg, null);
|
||||
|
||||
ImageView iv = new ImageView(image), iv2 = new ImageView(image);
|
||||
ImageView iv3 = new ImageView(), iv4 = new ImageView();
|
||||
Group blend = new Group(iv, iv3), blend2 = new Group(iv2, iv4);
|
||||
Group finalImg = new Group(blend), finalImg2 = new Group(blend2);
|
||||
|
||||
ScrollPane sp = new ScrollPane(finalImg), sp2 = new ScrollPane(finalImg2);
|
||||
sp.setPrefSize(300, 300);
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Blends the image plus user reference (cross-hair, etc.) with a black
|
||||
// rectangle to create final display
|
||||
//////////////////////////////////////////////////////////
|
||||
img = canvas.snapshot(null, null);
|
||||
iv3.setImage(img);
|
||||
iv4.setImage(img);
|
||||
Rectangle black = new Rectangle(width, height);
|
||||
|
||||
iv3.setBlendMode(BlendMode.DIFFERENCE);
|
||||
black.setFill(Color.BLACK);
|
||||
finalImg.setBlendMode(BlendMode.DIFFERENCE);
|
||||
sp.setContent(finalImg);
|
||||
|
||||
iv4.setBlendMode(BlendMode.DIFFERENCE);
|
||||
black.setFill(Color.BLACK);
|
||||
finalImg2.setBlendMode(BlendMode.DIFFERENCE);
|
||||
sp2.setContent(finalImg2);
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Creates another image view for the shrunken second image
|
||||
// Preserves the width-height ratio, but makes the larger quantity = 300
|
||||
// Does some math to figure what range-of-view rectangle height&width should be
|
||||
// and how the scroll bars will line up with the image
|
||||
/////////////////////////////////////////////
|
||||
ImageView imgZoom = new ImageView(image);
|
||||
imgZoom.setPreserveRatio(true);
|
||||
imgZoom.setFitHeight(300);
|
||||
imgZoom.setFitWidth(300);
|
||||
|
||||
double ratio = (double) 300 / (Math.max(height, width));
|
||||
double adjHeight = height * ratio, adjWidth = width * ratio;
|
||||
double rectHeight = 300 * ratio, rectWidth = 300 * ratio;
|
||||
|
||||
sp.setHmax(adjWidth - rectWidth);
|
||||
sp.setVmax(adjHeight - rectHeight);
|
||||
sp.setHvalue(sp.getHmax() / 2);
|
||||
sp.setVvalue(sp.getVmax() / 2);
|
||||
|
||||
Rectangle rect = new Rectangle(300 + sp.getHvalue(), sp.getVvalue(), rectWidth, rectHeight);
|
||||
rect.setStroke(Color.BLACK);
|
||||
rect.setFill(null);
|
||||
rect.setStrokeWidth(3);
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Creates labels, sliders, and value labels for RGB sliders
|
||||
// Sets wavelengths as values on slider, creates tick marks
|
||||
///////////////////////////////////////////////////////////
|
||||
ObservableList<String> items = FXCollections.observableArrayList("R770", "RBR", "BD530_2",
|
||||
"SH600_2", "SH770", "BD640_2", "BD860_2", "BD920_2", "RPEAK1", "BDI1000VIS", "R440", "IRR1",
|
||||
"BDI1000IR", "OLINDEX3", "R1330", "BD1300", "LCPINDEX2", "HCPINDEX2", "VAR", "ISLOPE1",
|
||||
"BD1400", "BD1435", "BD1500_2", "ICER1_2", "BD1750_2", "BD1900_2", "BD1900R2", "BDI2000",
|
||||
"BD2100_2", "BD2165", "BD2190", "MIN2200", "BD2210_2", "D2200", "BD2230", "BD2250",
|
||||
"MIN2250", "BD2265", "BD2290", "D2300", "BD2355", "SINDEX2", "ICER2_2", "MIN2295_2480",
|
||||
"MIN2345_2537", "BD2500_2", "BD3000", "BD3100", "BD3200", "BD3400_2", "CINDEX2", "BD2600",
|
||||
"IRR2", "IRR3", "R530", "R600", "R1080", "R1506", "R2529", "R3920");
|
||||
|
||||
summaryParameters = new ComboBox<>(items);
|
||||
Label nameSP = new Label("Current: None");
|
||||
|
||||
Button updateBtn = new Button("Update Image");
|
||||
Label subLabel = new Label();
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Creates coordinate label
|
||||
// Displays start row and column at center of image,
|
||||
// longitude and latitude
|
||||
/////////////////////////////////////////////////////
|
||||
longitude = CRISM.getLon(startRow, startCol);
|
||||
latitude = CRISM.getLat(startRow, startCol);
|
||||
Label crdValue =
|
||||
new Label("Data (row, col): (" + startRow + ", " + startCol + ")" + ", Latitude: "
|
||||
+ String.format("%.4f", latitude) + ", Longitude: " + String.format("%.4f", longitude));
|
||||
crdValue.setMinWidth(325);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Sets location of slider, coordinate objects in top-right section of grid pane
|
||||
// Sets the content of the different border/scroll panes
|
||||
////////////////////////////////////////////////////
|
||||
GridPane.setConstraints(crdValue, 1, 3);
|
||||
GridPane.setConstraints(updateBtn, 2, 3);
|
||||
GridPane.setConstraints(subLabel, 2, 4);
|
||||
|
||||
GridPane.setConstraints(summaryParameters, 1, 2);
|
||||
|
||||
GridPane.setConstraints(nameSP, 1, 4);
|
||||
|
||||
controls.getChildren().addAll(summaryParameters, crdValue, updateBtn, subLabel, nameSP);
|
||||
|
||||
borderTL.setLeft(sp);
|
||||
borderTL.setRight(imgZoom);
|
||||
borderLR.setLeft(borderTL);
|
||||
borderLR.getChildren().add(rect);
|
||||
borderLR.setRight(controls);
|
||||
borderTB.setTop(borderLR);
|
||||
mainSP.setContent(borderTB);
|
||||
mainSP.setFitToHeight(true);
|
||||
mainSP.setFitToWidth(true);
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Creates the scene and stage for the second window to be shown
|
||||
// Creates the scene for the expanded image, can close and reopen
|
||||
//////////////////////////////////////////////
|
||||
Scene scene2 = new Scene(root2);
|
||||
Stage stage2 = new Stage();
|
||||
stage2.setTitle(basefile);
|
||||
stage2.setScene(scene2);
|
||||
stage2.show();
|
||||
|
||||
Scene scene3 = new Scene(sp2, width, height);
|
||||
Stage stage3 = new Stage();
|
||||
stage3.setTitle(basefile);
|
||||
stage3.setScene(scene3);
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Gets the x, y, w, h of visible area in scroll pane
|
||||
// This is used during a subset stretch
|
||||
// NOTE: Must be run AFTER scene is shown for viewportBounds to exist
|
||||
//////////////////////////////////////////////
|
||||
double hmin = sp.getHmin(), hmax = sp.getHmax(), hvalue = sp.getHvalue();
|
||||
double contentWidth = iv.getLayoutBounds().getWidth() * (1 / scaleFactor);
|
||||
visW = (int) (sp.getViewportBounds().getWidth() * (1 / scaleFactor));
|
||||
visX = (int) (Math.max(0, contentWidth - visW) * (hvalue - hmin) / (hmax - hmin));
|
||||
|
||||
double vmin = sp.getVmin(), vmax = sp.getVmax(), vvalue = sp.getVvalue();
|
||||
double contentHeight = iv.getLayoutBounds().getHeight() * (1 / scaleFactor);
|
||||
visH = (int) (sp.getViewportBounds().getHeight() * (1 / scaleFactor));
|
||||
visY = (int) (Math.max(0, contentHeight - visH) * (vvalue - vmin) / (vmax - vmin));
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Opens a third window and expands image to its full size
|
||||
///////////////////////////////////////////////
|
||||
expandImg.setOnAction(event -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Expanding Image");
|
||||
stage3.show();
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Saves the currently shown image, with RGB values in filename
|
||||
//////////////////////////////////////////////////
|
||||
saveImg.setOnAction(event -> {
|
||||
|
||||
TextInputDialog input = new TextInputDialog();
|
||||
input.setTitle("File Name");
|
||||
input.setContentText("Set filename: ");
|
||||
String result = tidy(input.showAndWait());
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO,
|
||||
"Saving shown image to: " + result + ".png");
|
||||
|
||||
File f = new File(result + ".png");
|
||||
BufferedImage biSave = SwingFXUtils.fromFXImage(iv.getImage(), null);
|
||||
try {
|
||||
ImageIO.write(biSave, "PNG", f);
|
||||
} catch (IOException e1) {
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING, "Error saving image");
|
||||
e1.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Adjusts zoom of image, range-of-view rectangle size and sets scroll pane to
|
||||
// the same position
|
||||
//////////////////////////////////////////////////////
|
||||
zoomTG.selectedToggleProperty().addListener((obs, old_toggle, new_toggle) -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "Adjusting Zoom to selected level");
|
||||
scaleFactor = (zoom50.isSelected()) ? 0.5 : scaleFactor;
|
||||
scaleFactor = (zoom75.isSelected()) ? 0.75 : scaleFactor;
|
||||
scaleFactor = (zoom100.isSelected()) ? 1 : scaleFactor;
|
||||
scaleFactor = (zoom125.isSelected()) ? 1.25 : scaleFactor;
|
||||
scaleFactor = (zoom150.isSelected()) ? 1.5 : scaleFactor;
|
||||
scaleFactor = (zoom200.isSelected()) ? 2 : scaleFactor;
|
||||
int hVal = (int) sp.getHvalue();
|
||||
int vVal = (int) sp.getVvalue();
|
||||
int hMax = (int) sp.getHmax();
|
||||
int vMax = (int) sp.getVmax();
|
||||
iv.setPreserveRatio(true);
|
||||
iv.setFitHeight(height * scaleFactor);
|
||||
iv.setFitWidth(width * scaleFactor);
|
||||
iv3.setPreserveRatio(true);
|
||||
iv3.setFitHeight(height * scaleFactor);
|
||||
iv3.setFitWidth(width * scaleFactor);
|
||||
rect.setHeight(rectHeight * (1 / scaleFactor));
|
||||
rect.setWidth(rectWidth * (1 / scaleFactor));
|
||||
sp.setHmax(adjWidth - rect.getWidth());
|
||||
sp.setVmax(adjHeight - rect.getHeight());
|
||||
sp.setHvalue(hVal * (sp.getHmax() / hMax));
|
||||
sp.setVvalue(vVal * (sp.getVmax() / vMax));
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Sets the rectangle to correct position after scroll bars have been moved
|
||||
// Whenever scale or scroll bars change, the visible bounds adjust accordingly
|
||||
// This is important for the subset image stretches
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ChangeListener<Object> changeListener = new ChangeListener<Object>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Object> observable, Object oldValue,
|
||||
Object newValue) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method changed in launch class");
|
||||
double hmin = sp.getHmin(), hmax = sp.getHmax(), hvalue = sp.getHvalue();
|
||||
double contentWidth = iv.getLayoutBounds().getWidth() * (1 / scaleFactor);
|
||||
visW = (int) (sp.getViewportBounds().getWidth() * (1 / scaleFactor));
|
||||
visX = (int) (Math.max(0, contentWidth - visW) * (hvalue - hmin) / (hmax - hmin));
|
||||
rect.setX(300 + hvalue);
|
||||
|
||||
double vmin = sp.getVmin(), vmax = sp.getVmax(), vvalue = sp.getVvalue();
|
||||
double contentHeight = iv.getLayoutBounds().getHeight() * (1 / scaleFactor);
|
||||
visH = (int) (sp.getViewportBounds().getHeight() * (1 / scaleFactor));
|
||||
visY = (int) (Math.max(0, contentHeight - visH) * (vvalue - vmin) / (vmax - vmin));
|
||||
rect.setY(vvalue);
|
||||
}
|
||||
};
|
||||
sp.viewportBoundsProperty().addListener(changeListener);
|
||||
sp.hvalueProperty().addListener(changeListener);
|
||||
sp.vvalueProperty().addListener(changeListener);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Displays new row/col & lat/lon location whenever mouse moves on image
|
||||
// Row/col are 1:1 ratio with image, with (0, 0) at top left of both
|
||||
////////////////////////////////////////////////////
|
||||
finalImg.setOnMouseMoved(e -> {
|
||||
int newRow = (int) (e.getY() * (1 / scaleFactor));
|
||||
int newCol = (int) (e.getX() * (1 / scaleFactor));
|
||||
double longitude = CRISM.getLon(newRow, newCol);
|
||||
double latitude = CRISM.getLat(newRow, newCol);
|
||||
crdValue.setText("Data (row, col): (" + newRow + ", " + newCol + ")" + ", Latitude: "
|
||||
+ String.format("%.4f", latitude) + ", Longitude: " + String.format("%.4f", longitude)
|
||||
+ "\nValue: " + CRISM.getPCFloatValue(newRow, newCol, bandNum));
|
||||
});
|
||||
|
||||
finalImg2.setOnMouseMoved(e -> {
|
||||
int newRow = (int) (e.getY());
|
||||
int newCol = (int) (e.getX());
|
||||
double longitude = CRISM.getLon(newRow, newCol);
|
||||
double latitude = CRISM.getLat(newRow, newCol);
|
||||
crdValue.setText("Data (row, col): (" + newRow + ", " + newCol + ")" + "Latitude: "
|
||||
+ String.format("%.4f", latitude) + ", Longitude: " + String.format("%.4f", longitude));
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Gets the current chart, removes the RGB values and inputs the current values
|
||||
// Checks what is selected in contrast menu
|
||||
// Applies stretches with new RGB values
|
||||
// Checks whether subset stretch is selected,
|
||||
// Else use entire image for stretch
|
||||
///////////////////////////////////////////////////////////
|
||||
updateBtn.setOnAction(e -> {
|
||||
spCode = summaryParameters.getItems().indexOf(summaryParameters.getValue());
|
||||
|
||||
nameSP.setText("Current: " + CRISM.bandNames.get(spCode));
|
||||
|
||||
BufferedImage newBI = CRISM.getQuickColorImage(spCode, spCode, spCode);// CRISM.getQuickMonoImage(spNum);
|
||||
bImg = stretchImage(newBI);
|
||||
if (bImg != null && subStretch.isSelected())
|
||||
subLabel
|
||||
.setText("Row: " + visX + "-" + (visX + visW) + ", Col: " + visY + "-" + (visY + visH));
|
||||
else
|
||||
subLabel.setText(null);
|
||||
/*-
|
||||
List<Double> stretchValues = null;
|
||||
if (perCStretch.isSelected()) {
|
||||
TextInputDialog input = new TextInputDialog();
|
||||
input.setTitle("Percentile Stretch");
|
||||
input.setContentText("Input Percentile (Value): ");
|
||||
Optional<String> result = input.showAndWait();
|
||||
double stretch = Double.parseDouble(tidy(result));
|
||||
if (result.isPresent()) {
|
||||
if (subStretch.isSelected()) {
|
||||
stretchValues = getStretchValues(newBI.getSubimage(visX, visY, visW, visH), stretch);
|
||||
bImg = percentileSubStretch(newBI, stretchValues);
|
||||
subLabel.setText("Row: " + visX + "-" + (visX + visW) + ", Col: " + visY + "-" + (visY + visH));
|
||||
} else {
|
||||
bImg = percentileStretch(newBI, stretch);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (subStretch.isSelected()) {
|
||||
if (linStretch.isSelected()) {
|
||||
|
||||
stretchValues = getStretchValues(newBI.getSubimage(visX, visY, visW, visH), 0);
|
||||
bImg = linSubStretch(newBI, stretchValues);
|
||||
} else if (per1Stretch.isSelected()) {
|
||||
|
||||
stretchValues = getStretchValues(newBI.getSubimage(visX, visY, visW, visH), 1);
|
||||
bImg = percentileSubStretch(newBI, stretchValues);
|
||||
} else if (per2Stretch.isSelected()) {
|
||||
|
||||
stretchValues = getStretchValues(newBI.getSubimage(visX, visY, visW, visH), 2);
|
||||
bImg = percentileSubStretch(newBI, stretchValues);
|
||||
}
|
||||
subLabel.setText("Row: " + visX + "-" + (visX + visW) + ", Col: " + visY + "-" + (visY + visH));
|
||||
} else {
|
||||
bImg = (linStretch.isSelected()) ? linearStretch(newBI) : bImg;
|
||||
bImg = (per1Stretch.isSelected()) ? percentileStretch(newBI, 1) : bImg;
|
||||
bImg = (per2Stretch.isSelected()) ? percentileStretch(newBI, 2) : bImg;
|
||||
subLabel.setText(null);
|
||||
}
|
||||
}
|
||||
*/
|
||||
image = SwingFXUtils.toFXImage(bImg, null);
|
||||
iv.setImage(image);
|
||||
iv2.setImage(image);
|
||||
imgZoom.setImage(image);
|
||||
});
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Saves the input file to the recentFile.txt document for future use
|
||||
// Writes the property file for JCAT folder
|
||||
/////////////////////////////////////////////////
|
||||
saveRecentFiles(imgfile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
2202
src/main/java/javafx/TRDRBrowseProducts.java
Normal file
2202
src/main/java/javafx/TRDRBrowseProducts.java
Normal file
File diff suppressed because it is too large
Load Diff
1279
src/main/java/javafx/TRDRSummaryParameters.java
Normal file
1279
src/main/java/javafx/TRDRSummaryParameters.java
Normal file
File diff suppressed because it is too large
Load Diff
343
src/main/java/javafx/buildGUI.java
Normal file
343
src/main/java/javafx/buildGUI.java
Normal file
@@ -0,0 +1,343 @@
|
||||
package javafx;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.TextArea;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Optional;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ChoiceDialog;
|
||||
import javafx.scene.control.Dialog;
|
||||
import javafx.scene.control.Menu;
|
||||
import javafx.scene.control.MenuBar;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.SeparatorMenuItem;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import util.AppVersion;
|
||||
import util.JCATConfig;
|
||||
import util.JCATLog;
|
||||
import util.JCATMessageWindow;
|
||||
|
||||
public class buildGUI extends launch {
|
||||
|
||||
public static void main(String args[]) {
|
||||
Application.launch(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) {
|
||||
try {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, AppVersion.getVersionString());
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO,
|
||||
"Running Java " + System.getProperty("java.version"));
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Initiating UI");
|
||||
initUI(stage);
|
||||
} catch (Exception e) {
|
||||
JCATLog.getInstance().getLogger().log(Level.SEVERE, "UI failed to initiate");
|
||||
JCATMessageWindow.show(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void initUI(Stage stage1) throws Exception {
|
||||
///////////////////////////////////////////////////////////
|
||||
// Creates main window, adds File, Browser and Help menus with menu items
|
||||
///////////////////////////////////////////////////////////
|
||||
HBox root1 = new HBox();
|
||||
Scene scene1 = new Scene(root1, 400, 200);
|
||||
stage1.setTitle("Java CRISM Analysis Tool");
|
||||
stage1.setScene(scene1);
|
||||
stage1.setOnCloseRequest(e -> Platform.exit());
|
||||
stage1.show();
|
||||
|
||||
MenuBar mbar = new MenuBar();
|
||||
mbar.prefWidthProperty().bind(stage1.widthProperty());
|
||||
|
||||
Menu fileMenu = new Menu("File");
|
||||
Menu browserMenu = new Menu("Browser");
|
||||
Menu helpMenu = new Menu("Help");
|
||||
mbar.getMenus().addAll(fileMenu, browserMenu, helpMenu);
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Launches window with filename, from home directory or recent files list
|
||||
////////////////////////////////////////////
|
||||
MenuItem newFile = new MenuItem("New");
|
||||
fileMenu.getItems().add(newFile);
|
||||
newFile.setOnAction(event -> {
|
||||
try {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Attempting to open new file");
|
||||
FileChooser fc = new FileChooser();
|
||||
fc.setTitle("New File");
|
||||
configureFileChooser(fc);
|
||||
File selectedFile = fc.showOpenDialog(stage1);
|
||||
if (selectedFile != null) {
|
||||
String imgname = selectedFile.toString();
|
||||
String basefile = FilenameUtils.getFullPath(imgname) + FilenameUtils.getBaseName(imgname);
|
||||
String imgfile = String.format("%s.%s", basefile, FilenameUtils.getExtension(imgname));
|
||||
|
||||
if (FilenameUtils.getBaseName(imgname).substring(15).toLowerCase().startsWith("su")) {
|
||||
MTRDRSummaryParameters j = new MTRDRSummaryParameters();
|
||||
if (!j.create(imgfile, basefile)) {
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING,
|
||||
"Error opening file: " + imgname);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
launch j = new launch();
|
||||
if (!j.create(imgfile, basefile)) {
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING,
|
||||
"Error opening file: " + imgname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO,
|
||||
"New file opened successfully: " + imgname);
|
||||
JCATConfig.getInstance().setLastDirectory(FilenameUtils.getFullPath(imgname));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
JCATMessageWindow.show(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
MenuItem recentFile = new MenuItem("Recent");
|
||||
fileMenu.getItems().add(recentFile);
|
||||
recentFile.setOnAction(event -> {
|
||||
try {
|
||||
Vector<String> RecentFiles = getRecentFiles();
|
||||
if (RecentFiles.size() > 0) {
|
||||
String recFiles = RecentFiles.get(0);
|
||||
ChoiceDialog<String> dialog = new ChoiceDialog<>(recFiles, RecentFiles);
|
||||
dialog.setTitle("Recent Files");
|
||||
dialog.setContentText("Choose a file: ");
|
||||
Optional<String> imgname = dialog.showAndWait();
|
||||
if (imgname.isPresent()) {
|
||||
String imgfile = tidy(imgname); // Changes type Optional<String> to String
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Opening recent file: " + imgfile);
|
||||
String basefile = imgfile.replace(".img", "");
|
||||
|
||||
if (FilenameUtils.getBaseName(basefile).substring(15).toLowerCase().startsWith("su")) {
|
||||
MTRDRSummaryParameters j = new MTRDRSummaryParameters();
|
||||
if (!j.create(imgfile, basefile)) {
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING,
|
||||
"Error opening file: " + imgfile);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
launch j = new launch();
|
||||
if (!j.create(imgfile, basefile)) {
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING,
|
||||
"Error opening file: " + imgfile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "File opened: " + imgfile);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING,
|
||||
"Something went wrong opening recent file");
|
||||
JCATMessageWindow.show(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
// Creates the menu item that displays the log when pressed
|
||||
MenuItem log = new MenuItem("Show Log");
|
||||
helpMenu.getItems().add(log);
|
||||
log.setOnAction(e -> {
|
||||
new logWindow();
|
||||
});
|
||||
|
||||
fileMenu.getItems().add(new SeparatorMenuItem());
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Open browser to CRISM Map, PDS Data Product Repository, PDS Data Product
|
||||
///////////////////////////////////////////////// Search
|
||||
/////////////////////////////////////////////////
|
||||
MenuItem CRISMBrowser = new MenuItem("CRISM MAP");
|
||||
browserMenu.getItems().add(CRISMBrowser);
|
||||
CRISMBrowser.setOnAction(event -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Opening CRISM Map");
|
||||
getHostServices().showDocument("http://crism-map.jhuapl.edu/");
|
||||
});
|
||||
|
||||
MenuItem PDSDPRBrowser = new MenuItem("PDS Data Product Repository");
|
||||
browserMenu.getItems().add(PDSDPRBrowser);
|
||||
PDSDPRBrowser.setOnAction(event -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Opening PDS Data Product Repository");
|
||||
getHostServices().showDocument("http://pds-geosciences.wustl.edu/missions/mro/crism.htm");
|
||||
});
|
||||
|
||||
MenuItem PDSDPSBrowser = new MenuItem("PDS Data Product Search");
|
||||
browserMenu.getItems().add(PDSDPSBrowser);
|
||||
PDSDPSBrowser.setOnAction(event -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Opening PDS Data Product Search");
|
||||
getHostServices().showDocument("http://ode.rsl.wustl.edu/mars/indexproductsearch.aspx");
|
||||
});
|
||||
|
||||
MenuItem docHelp = new MenuItem("Tutorial");
|
||||
helpMenu.getItems().add(docHelp);
|
||||
docHelp.setOnAction(event -> {
|
||||
try {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Opening tutorial");
|
||||
File f = new File(
|
||||
JCATConfig.getInstance().getLocalArchive() + File.separator + "JCAT_Tutorial.pdf");
|
||||
FileUtils.copyInputStreamToFile(
|
||||
getClass().getResourceAsStream("/resources/JCAT_Tutorial.pdf"), f);
|
||||
getHostServices().showDocument(f.toURI().toString());
|
||||
} catch (Exception e) {
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING, "Error getting documentation");
|
||||
JCATMessageWindow.show(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Display current JCAT Version Number
|
||||
//////////////////////////////////////////////////////////////
|
||||
MenuItem aboutHelp = new MenuItem("About");
|
||||
helpMenu.getItems().add(aboutHelp);
|
||||
aboutHelp.setOnAction(event -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Showing JCAT Version");
|
||||
VBox vbox = new VBox();
|
||||
Dialog<Boolean> d = new Dialog<Boolean>();
|
||||
d.setTitle("About");
|
||||
d.setHeaderText(AppVersion.getVersionString());
|
||||
d.setContentText(
|
||||
"Authors: \nDavid Stephens \nMichael Chen \nAntonio Karides \nHari Nair\n\nFor support, please contact Hari.Nair@jhuapl.edu \n\nJohns Hopkins University Applied Physics Lab");
|
||||
d.setGraphic(vbox);
|
||||
Button close = new Button("Close");
|
||||
vbox.getChildren().add(close);
|
||||
d.show();
|
||||
close.setOnAction(e -> {
|
||||
d.setResult(Boolean.TRUE);
|
||||
d.close();
|
||||
});
|
||||
});
|
||||
|
||||
MenuItem quit = new MenuItem("Quit");
|
||||
quit.setOnAction(event -> {
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Quitting JCAT");
|
||||
Platform.exit();
|
||||
});
|
||||
|
||||
fileMenu.getItems().add(quit);
|
||||
root1.getChildren().add(mbar);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Sets initial directory and .img extension filters
|
||||
///////////////////////////////////////////////////////////
|
||||
public void configureFileChooser(final FileChooser fileChooser) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST,
|
||||
"Entering method configureFileChooser in buildGUI class");
|
||||
fileChooser.setInitialDirectory(JCATConfig.getInstance().getLastWorkingDirectory());
|
||||
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("IMG", "*.img"));
|
||||
}
|
||||
|
||||
public class logWindow {
|
||||
|
||||
private JFrame frmLog;
|
||||
private JComboBox<Level> levels;
|
||||
private TextArea logMessages;
|
||||
|
||||
public logWindow() {
|
||||
levels = new JComboBox<Level>();
|
||||
levels.setBounds(12, 13, 223, 36);
|
||||
levels.setModel(new DefaultComboBoxModel<Level>(new Level[] {Level.SEVERE, Level.WARNING,
|
||||
Level.INFO, Level.CONFIG, Level.FINE, Level.FINER, Level.FINEST}));
|
||||
|
||||
levels.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ArrayList<String> messages =
|
||||
(JCATLog.getInstance().getLog((Level) levels.getSelectedItem()));
|
||||
String allMessages = "";
|
||||
for (String a : messages)
|
||||
allMessages += a.toString() + "\n";
|
||||
|
||||
logMessages.setText(allMessages);
|
||||
}
|
||||
});
|
||||
|
||||
initialize();
|
||||
|
||||
JButton btnSave = new JButton("Save");
|
||||
btnSave.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
|
||||
int retrival = chooser.showSaveDialog(null);
|
||||
if (retrival == JFileChooser.APPROVE_OPTION) {
|
||||
|
||||
try (FileWriter fw = new FileWriter(chooser.getSelectedFile() + ".txt")) {
|
||||
fw.write(logMessages.getText());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
btnSave.setBounds(523, 377, 97, 25);
|
||||
frmLog.getContentPane().add(btnSave);
|
||||
|
||||
frmLog.setLocationRelativeTo(null);
|
||||
frmLog.setVisible(true);
|
||||
}
|
||||
|
||||
public TextArea getText() {
|
||||
return logMessages;
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
frmLog = new JFrame();
|
||||
frmLog.setResizable(false);
|
||||
frmLog.setTitle("JCAT Log");
|
||||
frmLog.setBounds(100, 100, 650, 444);
|
||||
frmLog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
frmLog.getContentPane().setLayout(null);
|
||||
|
||||
frmLog.getContentPane().add(levels);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Log",
|
||||
TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
|
||||
panel.setBounds(12, 51, 608, 319);
|
||||
frmLog.getContentPane().add(panel);
|
||||
panel.setLayout(null);
|
||||
|
||||
logMessages = new TextArea();
|
||||
logMessages.setEditable(false);
|
||||
logMessages.setBounds(6, 20, 592, 293);
|
||||
panel.add(logMessages);
|
||||
|
||||
levels.setSelectedItem(Level.INFO);
|
||||
levels.getActionListeners()[0].actionPerformed(null);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
2067
src/main/java/javafx/launch.java
Normal file
2067
src/main/java/javafx/launch.java
Normal file
File diff suppressed because it is too large
Load Diff
49
src/main/java/reader/ADR.java
Normal file
49
src/main/java/reader/ADR.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package reader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import definition.PDS.PDSObject;
|
||||
import util.JCATLog;
|
||||
|
||||
public class ADR extends CRISMPDSImageFirstGen {
|
||||
|
||||
public ADR(String filename) {
|
||||
super(filename);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating ADR object");
|
||||
String tick = imgLabel.getStringNoQuotes("SPACECRAFT_CLOCK_START_COUNT");
|
||||
int p = tick.indexOf("/");
|
||||
sclk = Integer.parseInt(tick.substring(p + 1, 11));
|
||||
}
|
||||
|
||||
public List<Double> getTrans(int col, List<Integer> gbBands) {
|
||||
List<Double> vstrans = new ArrayList<Double>();
|
||||
for (int i = 0; i < this.totalBands(); i++) {
|
||||
float a = this.getPCFloatValue(0, col, i); // first line is transmission spectrum
|
||||
if (gbBands.get(i) == 1) {
|
||||
vstrans.add(Double.valueOf(a));
|
||||
}
|
||||
}
|
||||
return vstrans;
|
||||
}
|
||||
|
||||
public List<Double> getArt(int col, List<Integer> gbBands) {
|
||||
List<Double> vsart = new ArrayList<Double>();
|
||||
for (int i = 0; i < this.totalBands(); i++) {
|
||||
float a = this.getPCFloatValue(1, col, i); // second line is McGuire artifact
|
||||
if (gbBands.get(i) == 1) {
|
||||
vsart.add(Double.valueOf(a));
|
||||
}
|
||||
}
|
||||
return vsart;
|
||||
}
|
||||
|
||||
public int totalBands() {
|
||||
PDSObject fileObj = imgLabel.findObject("FILE");
|
||||
PDSObject imgObj = fileObj.findObject("IMAGE");
|
||||
int bands = imgObj.getInt("BANDS");
|
||||
return bands;
|
||||
}
|
||||
|
||||
}
|
||||
61
src/main/java/reader/ADRPairings.java
Normal file
61
src/main/java/reader/ADRPairings.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package reader;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import util.JCATLog;
|
||||
|
||||
public class ADRPairings {
|
||||
|
||||
private HashMap<String, String> adrPairs;
|
||||
|
||||
public String getADRPair(String obsID) {
|
||||
String adrID = adrPairs.get(obsID);
|
||||
return adrID;
|
||||
}
|
||||
|
||||
public ADRPairings() {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating ADRPairings object");
|
||||
adrPairs = new HashMap<>();
|
||||
try {
|
||||
readVSLookup();
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void readVSLookup() throws URISyntaxException {
|
||||
String swPath = "/resources/vs/lookup";
|
||||
URI uri = this.getClass().getResource(swPath).toURI();
|
||||
Path myPath = Paths.get(uri);
|
||||
File f = new File(myPath + "/crism_obs_info.txt");
|
||||
if (f.exists()) {
|
||||
try {
|
||||
BufferedReader in = new BufferedReader(new FileReader(f));
|
||||
String line = null;
|
||||
while ((line = in.readLine()) != null) {
|
||||
String[] parts = line.split("\\s+");
|
||||
if (!parts[1].equals("65.535")) {
|
||||
adrPairs.put(parts[1].toLowerCase(), parts[6]); // gets the pair using McGuire
|
||||
// wavelengths
|
||||
}
|
||||
}
|
||||
in.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
77
src/main/java/reader/ADRVSLibrary.java
Normal file
77
src/main/java/reader/ADRVSLibrary.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package reader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import util.JCATConfig;
|
||||
import util.JCATLog;
|
||||
|
||||
public class ADRVSLibrary {
|
||||
|
||||
private Set<String> vsNames;
|
||||
private final String vsPath = "/resources/adr/vs";
|
||||
|
||||
public Set<String> getNames() {
|
||||
return vsNames;
|
||||
}
|
||||
|
||||
public String getLocalPath() {
|
||||
return JCATConfig.getInstance().getLocalArchive() + File.separator + "vs";
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return vsPath;
|
||||
}
|
||||
|
||||
private static ADRVSLibrary instance = null;
|
||||
|
||||
public static ADRVSLibrary getInstance() {
|
||||
if (instance == null)
|
||||
instance = new ADRVSLibrary();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ADRVSLibrary() {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating ADRVSLibrary object");
|
||||
vsNames = new HashSet<>();
|
||||
try {
|
||||
readResources();
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void readResources() throws URISyntaxException, IOException {
|
||||
URI uri = this.getClass().getResource(vsPath).toURI();
|
||||
Path myPath;
|
||||
|
||||
JCATConfig config = JCATConfig.getInstance();
|
||||
if (config.fromJar()) {
|
||||
myPath = config.getJarFileSystem().getPath(vsPath);
|
||||
} else {
|
||||
myPath = Paths.get(uri);
|
||||
}
|
||||
|
||||
try (Stream<Path> walk = Files.walk(myPath, 1)) {
|
||||
for (Iterator<Path> it = walk.iterator(); it.hasNext();) {
|
||||
Path path = it.next();
|
||||
if (path.toString().endsWith("IMG")) {
|
||||
vsNames.add(FilenameUtils.getBaseName(path.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
401
src/main/java/reader/CRISMPDSImage.java
Normal file
401
src/main/java/reader/CRISMPDSImage.java
Normal file
@@ -0,0 +1,401 @@
|
||||
package reader;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
|
||||
|
||||
import definition.PDS.PDSImage;
|
||||
import definition.PDS.PDSLabel;
|
||||
import util.JCATLog;
|
||||
|
||||
public abstract class CRISMPDSImage extends PDSImage {
|
||||
protected PDSLabel imgLabel = null;
|
||||
protected PDSLabel waLabel = null;
|
||||
protected String imgFilename = "";
|
||||
protected String lblFilename = "";
|
||||
|
||||
protected LinkedHashMap<Integer, Double> bandMap;
|
||||
|
||||
protected int numBands;
|
||||
protected double[] bands;
|
||||
|
||||
protected double westLon;
|
||||
protected double eastLon;
|
||||
protected double maxLat;
|
||||
protected double minLat;
|
||||
protected int minLine;
|
||||
protected int maxLine;
|
||||
protected int minSample;
|
||||
protected int maxSample;
|
||||
|
||||
protected double[][] lat;
|
||||
protected double[][] lon;
|
||||
protected int inaIndex;
|
||||
protected int bc;
|
||||
protected int wv;
|
||||
protected int sclk;
|
||||
protected List<Integer> detector;
|
||||
|
||||
public int getsclk() {
|
||||
return sclk;
|
||||
}
|
||||
|
||||
public int getINA() {
|
||||
return inaIndex;
|
||||
}
|
||||
|
||||
public int getBC() {
|
||||
return bc;
|
||||
}
|
||||
|
||||
public int getWV() {
|
||||
return wv;
|
||||
}
|
||||
|
||||
protected boolean haveMapBounds;
|
||||
|
||||
public double getWestLonDegrees() {
|
||||
return westLon;
|
||||
}
|
||||
|
||||
public double getMaxLatDegrees() {
|
||||
return maxLat;
|
||||
}
|
||||
|
||||
public double getEastLonDegrees() {
|
||||
return eastLon;
|
||||
}
|
||||
|
||||
public double getMinLatDegrees() {
|
||||
return minLat;
|
||||
}
|
||||
|
||||
public int getMinLine() {
|
||||
return minLine;
|
||||
}
|
||||
|
||||
public int getMaxLine() {
|
||||
return maxLine;
|
||||
}
|
||||
|
||||
public int getMinSample() {
|
||||
return minSample;
|
||||
}
|
||||
|
||||
public int getMaxSample() {
|
||||
return maxSample;
|
||||
}
|
||||
|
||||
public boolean haveMapBounds() {
|
||||
return haveMapBounds;
|
||||
}
|
||||
|
||||
public double getLat(int row, int col) {
|
||||
if (haveMapBounds && (row < lon.length && col < lon[row].length))
|
||||
return lat[row][col];
|
||||
else
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
public double getLon(int row, int col) {
|
||||
|
||||
if (haveMapBounds && (row < lon.length && col < lon[row].length))
|
||||
return lon[row][col];
|
||||
else
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
public CRISMPDSImage(String filename) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating CRISMPDSImage object");
|
||||
haveMapBounds = false;
|
||||
|
||||
String name = filename.trim();
|
||||
|
||||
if (name.toUpperCase().endsWith(".IMG")) {
|
||||
|
||||
imgFilename = name;
|
||||
lblFilename = FilenameUtils.getFullPath(name) + FilenameUtils.getBaseName(name);
|
||||
|
||||
if (name.endsWith(".IMG"))
|
||||
lblFilename += ".LBL";
|
||||
else
|
||||
lblFilename += ".lbl";
|
||||
|
||||
//
|
||||
|
||||
} else if (name.toUpperCase().endsWith(".LBL")) {
|
||||
// imgLabel = new PDSLabel(name);
|
||||
|
||||
lblFilename = name;
|
||||
imgFilename = FilenameUtils.getFullPath(name) + FilenameUtils.getBaseName(name);
|
||||
|
||||
if (name.endsWith(".LBL"))
|
||||
imgFilename += ".IMG";
|
||||
else
|
||||
imgFilename += ".img";
|
||||
}
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.INFO, "Reading Label file from: " + lblFilename);
|
||||
imgLabel = new PDSLabel(lblFilename);
|
||||
|
||||
if (!imgLabel.isValidLabel()) {
|
||||
String s = "Invalid/missing label file: " + FilenameUtils.getName(lblFilename);
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING, s);
|
||||
} else
|
||||
create();
|
||||
|
||||
}
|
||||
|
||||
abstract protected void create();
|
||||
|
||||
public double getWavelength(int band) {
|
||||
return bandMap.get(band);
|
||||
}
|
||||
|
||||
public List<Integer> getDetector() {
|
||||
return detector;
|
||||
}
|
||||
|
||||
public List<Integer> getBandIndices() {
|
||||
return new ArrayList<Integer>(bandMap.keySet());
|
||||
}
|
||||
|
||||
public List<Double> getWavelengths() {
|
||||
List<Double> wavelengths = new ArrayList<>(bandMap.values());
|
||||
return wavelengths;
|
||||
}
|
||||
|
||||
public int getNumBands() {
|
||||
return bandMap.keySet().size();
|
||||
}
|
||||
|
||||
public double[][] getBandData(int bandIndex) {
|
||||
int w = (int) getWidth();
|
||||
int h = (int) getHeight();
|
||||
double[][] array = new double[w][h];
|
||||
|
||||
for (int row = 0; row < h; row++) {
|
||||
for (int col = 0; col < w; col++) {
|
||||
array[col][row] = getPCFloatValue(row, col, bandIndex);
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public BufferedImage getQuickMonoImage(int bandIndex) {
|
||||
|
||||
BufferedImage result = null;
|
||||
|
||||
int w = (int) getWidth();
|
||||
int h = (int) getHeight();
|
||||
|
||||
if ((w > 0) && (h > 0)) {
|
||||
|
||||
DescriptiveStatistics xStats = new DescriptiveStatistics();
|
||||
|
||||
result = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
|
||||
|
||||
Graphics gfx = result.getGraphics();
|
||||
gfx.setColor(Color.black);
|
||||
gfx.fillRect(0, 0, w, h);
|
||||
|
||||
for (int row = 0; row < h; row++) {
|
||||
for (int col = 0; col < w; col++) {
|
||||
float x = getPCFloatValue(row, col, bandIndex);
|
||||
if (x > 32768)
|
||||
continue;
|
||||
xStats.addValue(x);
|
||||
}
|
||||
}
|
||||
|
||||
final double minVal = xStats.getMin();
|
||||
final double maxVal = xStats.getMax();
|
||||
for (int row = 0; row < h; row++) {
|
||||
for (int col = 0; col < w; col++) {
|
||||
float x = getPCFloatValue(row, col, bandIndex);
|
||||
int R = (int) (255 * (x - minVal) / (maxVal - minVal));
|
||||
result.setRGB(col, row, ((R << 16) | (R << 8) | R));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public BufferedImage getQuickColorImage(int red, int green, int blue) {
|
||||
|
||||
BufferedImage result = null;
|
||||
|
||||
int w = (int) getWidth();
|
||||
int h = (int) getHeight();
|
||||
|
||||
int row, col, rgb;
|
||||
float x, y, z;// , v1, v2, v3;
|
||||
int R, G, B;
|
||||
|
||||
cacheEntireImage();
|
||||
|
||||
if ((w > 0) && (h > 0)) {
|
||||
|
||||
DescriptiveStatistics xStats = new DescriptiveStatistics();
|
||||
DescriptiveStatistics yStats = new DescriptiveStatistics();
|
||||
DescriptiveStatistics zStats = new DescriptiveStatistics();
|
||||
|
||||
result = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
|
||||
|
||||
Graphics gfx = result.getGraphics();
|
||||
gfx.setColor(Color.black);
|
||||
gfx.fillRect(0, 0, w, h);
|
||||
|
||||
ArrayList<Float> redBand = new ArrayList<>();
|
||||
ArrayList<Float> grnBand = new ArrayList<>();
|
||||
ArrayList<Float> bluBand = new ArrayList<>();
|
||||
|
||||
for (row = 0; row < h; row++) {
|
||||
for (col = 0; col < w; col++) {
|
||||
x = getPCFloatValue(row, col, red);
|
||||
if (x != 65535)
|
||||
xStats.addValue(x);
|
||||
redBand.add(x);
|
||||
}
|
||||
}
|
||||
|
||||
for (row = 0; row < h; row++) {
|
||||
for (col = 0; col < w; col++) {
|
||||
y = getPCFloatValue(row, col, green);
|
||||
if (y != 65535)
|
||||
yStats.addValue(y);
|
||||
grnBand.add(y);
|
||||
}
|
||||
}
|
||||
|
||||
for (row = 0; row < h; row++) {
|
||||
for (col = 0; col < w; col++) {
|
||||
z = getPCFloatValue(row, col, blue);
|
||||
if (z != 65535)
|
||||
zStats.addValue(z);
|
||||
bluBand.add(z);
|
||||
}
|
||||
}
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "red stats:\n" + xStats);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "green stats:\n" + yStats);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "blue stats:\n" + zStats);
|
||||
|
||||
final double xMin = xStats.getMin();
|
||||
final double yMin = yStats.getMin();
|
||||
final double zMin = zStats.getMin();
|
||||
double scale = 255 / (Math.max(xStats.getMax() - xMin,
|
||||
Math.max(yStats.getMax() - yMin, zStats.getMax() - zMin)));
|
||||
float min = (float) Math.min(xStats.getMin(), Math.min(yStats.getMin(), zStats.getMin()));
|
||||
|
||||
for (int i = 0; i < redBand.size(); i++) {
|
||||
col = i % w;
|
||||
row = i / w;
|
||||
x = redBand.get(i) - min;
|
||||
y = grnBand.get(i) - min;
|
||||
z = bluBand.get(i) - min;
|
||||
R = Math.min((int) (0.50 + scale * x), 255);
|
||||
G = Math.min((int) (0.50 + scale * y), 255);
|
||||
B = Math.min((int) (0.50 + scale * z), 255);
|
||||
|
||||
rgb = (R << 16) | (G << 8) | B;
|
||||
result.setRGB(col, row, rgb);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public BufferedImage getQuickColorImage(float[][] redBand, float[][] grnBand, float[][] bluBand) {
|
||||
|
||||
BufferedImage result = null;
|
||||
|
||||
int w = (int) getWidth();
|
||||
int h = (int) getHeight();
|
||||
|
||||
int rgb;
|
||||
float x, y, z;// , v1, v2, v3;
|
||||
int R, G, B;
|
||||
|
||||
cacheEntireImage();
|
||||
|
||||
if ((w > 0) && (h > 0)) {
|
||||
|
||||
DescriptiveStatistics xStats = new DescriptiveStatistics();
|
||||
DescriptiveStatistics yStats = new DescriptiveStatistics();
|
||||
DescriptiveStatistics zStats = new DescriptiveStatistics();
|
||||
|
||||
for (int row = 0; row < h; row++) {
|
||||
for (int col = 0; col < w; col++) {
|
||||
x = redBand[row][col];
|
||||
if (x != 65535)
|
||||
xStats.addValue(x);
|
||||
}
|
||||
}
|
||||
|
||||
for (int row = 0; row < h; row++) {
|
||||
for (int col = 0; col < w; col++) {
|
||||
y = grnBand[row][col];
|
||||
if (y != 65535)
|
||||
yStats.addValue(y);
|
||||
}
|
||||
}
|
||||
|
||||
for (int row = 0; row < h; row++) {
|
||||
for (int col = 0; col < w; col++) {
|
||||
z = bluBand[row][col];
|
||||
if (z != 65535)
|
||||
zStats.addValue(z);
|
||||
}
|
||||
}
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "red stats:\n" + xStats);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "green stats:\n" + yStats);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "blue stats:\n" + zStats);
|
||||
|
||||
result = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
|
||||
|
||||
Graphics gfx = result.getGraphics();
|
||||
gfx.setColor(Color.black);
|
||||
gfx.fillRect(0, 0, w, h);
|
||||
|
||||
final double xMin = xStats.getMin();
|
||||
final double yMin = yStats.getMin();
|
||||
final double zMin = zStats.getMin();
|
||||
double scale = 255 / (Math.max(xStats.getMax() - xMin,
|
||||
Math.max(yStats.getMax() - yMin, zStats.getMax() - zMin)));
|
||||
float min = (float) Math.min(xStats.getMin(), Math.min(yStats.getMin(), zStats.getMin()));
|
||||
|
||||
for (int row = 0; row < h; row++) {
|
||||
for (int col = 0; col < w; col++) {
|
||||
|
||||
x = redBand[row][col] - min;
|
||||
y = grnBand[row][col] - min;
|
||||
z = bluBand[row][col] - min;
|
||||
R = Math.min((int) (0.50 + scale * x), 255);
|
||||
G = Math.min((int) (0.50 + scale * y), 255);
|
||||
B = Math.min((int) (0.50 + scale * z), 255);
|
||||
|
||||
rgb = (R << 16) | (G << 8) | B;
|
||||
result.setRGB(col, row, rgb);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public String getImgname() {
|
||||
return imgFilename;
|
||||
}
|
||||
|
||||
}
|
||||
60
src/main/java/reader/CRISMPDSImageFirstGen.java
Normal file
60
src/main/java/reader/CRISMPDSImageFirstGen.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package reader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import definition.PDS.PDSObject;
|
||||
import util.JCATLog;
|
||||
|
||||
public class CRISMPDSImageFirstGen extends CRISMPDSImage {
|
||||
|
||||
protected List<Integer> rowNumbers;
|
||||
|
||||
public CRISMPDSImageFirstGen(String filename) {
|
||||
super(filename);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER,
|
||||
"Instantiating CRISMPDSImageFirstGen object");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void create() {
|
||||
|
||||
PDSObject fileObj = imgLabel.findObject("FILE");
|
||||
if (fileObj == null)
|
||||
throw new NullPointerException("No FILE object found in " + lblFilename);
|
||||
|
||||
PDSObject imgObj = fileObj.findObject("IMAGE");
|
||||
if (imgObj == null)
|
||||
throw new NullPointerException("No IMAGE object found in " + lblFilename);
|
||||
|
||||
createImage(imgFilename, imgObj);
|
||||
|
||||
PDSObject rowObj = fileObj.findObject("ROWNUM_TABLE");
|
||||
if (rowObj != null) {
|
||||
int rows = rowObj.getInt("ROWS");
|
||||
|
||||
if (rows > 0) {
|
||||
if (rowNumbers == null)
|
||||
rowNumbers = new Vector<Integer>(rows);
|
||||
|
||||
int recBytes = fileObj.getInt("RECORD_BYTES");
|
||||
int numFileRecs = fileObj.getInt("FILE_RECORDS");
|
||||
long totalFileSize = recBytes * numFileRecs;
|
||||
|
||||
long numImageRecs = (imageWidth * imageHeight * bandCount * dataBitCount / 8) / recBytes;
|
||||
|
||||
long offset = numImageRecs * recBytes;
|
||||
|
||||
while ((offset < totalFileSize) && (rowNumbers.size() < rows)) {
|
||||
int rowNum = getShortValue(offset);
|
||||
|
||||
rowNumbers.add(rowNum);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
178
src/main/java/reader/CRISMPDSImageNextGen.java
Normal file
178
src/main/java/reader/CRISMPDSImageNextGen.java
Normal file
@@ -0,0 +1,178 @@
|
||||
package reader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import definition.PDS.PDSObject;
|
||||
import util.JCATLog;
|
||||
|
||||
public class CRISMPDSImageNextGen extends CRISMPDSImage {
|
||||
|
||||
private DDR ddr;
|
||||
public LinkedHashMap<Integer, String> bandMapSU;
|
||||
|
||||
public CRISMPDSImageNextGen(String filename) {
|
||||
|
||||
this(filename, null);
|
||||
|
||||
}
|
||||
|
||||
public CRISMPDSImageNextGen(String filename, String ddrFilename) {
|
||||
super(filename);
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating CRISMPDSImageNextGen object");
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Creating CRISMPDSImageNextGen object");
|
||||
String wavelengthTable =
|
||||
FilenameUtils.getFullPath(filename) + FilenameUtils.getName(filename).replaceAll("if", "wv")
|
||||
.replaceAll(".img", ".tab").replaceAll("IF", "WV").replaceAll(".IMG", ".TAB");
|
||||
|
||||
if (FilenameUtils.getBaseName(filename).substring(22).toLowerCase().startsWith("ter")) {
|
||||
ddrFilename = filename.replaceAll("if", "de").replaceAll("j", "l").replaceAll("ter3", "ddr1")
|
||||
.replaceAll("IF", "DE").replaceAll("J", "L").replaceAll("TER3", "DDR1");
|
||||
ddr = (new File(ddrFilename).exists() ? new DDR(ddrFilename) : null);
|
||||
|
||||
if (ddr != null) {
|
||||
int latIndex = ddr.findBandNumber("Latitude, areocentric, deg N");
|
||||
int lonIndex = ddr.findBandNumber("Longitude, areocentric, deg E");
|
||||
|
||||
lat = new double[(int) ddr.getHeight()][(int) ddr.getWidth()];
|
||||
lon = new double[(int) ddr.getHeight()][(int) ddr.getWidth()];
|
||||
|
||||
minLat = Double.MAX_VALUE;
|
||||
maxLat = -Double.MAX_VALUE;
|
||||
westLon = Double.MAX_VALUE;
|
||||
eastLon = -Double.MAX_VALUE;
|
||||
|
||||
for (int row = 0; row < ddr.getHeight(); row++) {
|
||||
for (int col = 0; col < ddr.getWidth(); col++) {
|
||||
float thisLat = ddr.getPCFloatValue(row, col, latIndex);
|
||||
if (thisLat < 32768) {
|
||||
maxLat = Math.max(maxLat, thisLat);
|
||||
minLat = Math.min(minLat, thisLat);
|
||||
lat[row][col] = thisLat;
|
||||
}
|
||||
|
||||
float thisLon = ddr.getPCFloatValue(row, col, lonIndex);
|
||||
|
||||
if (thisLon < 32768) {
|
||||
eastLon = Math.max(eastLon, thisLon);
|
||||
westLon = Math.min(westLon, thisLon);
|
||||
lon[row][col] = thisLon;
|
||||
// check if we're crossing the 0 degree line
|
||||
if (eastLon - westLon > 180) {
|
||||
double tmp = eastLon;
|
||||
eastLon = westLon;
|
||||
westLon = tmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
haveMapBounds = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
detector = new ArrayList<Integer>();
|
||||
|
||||
if (FilenameUtils.getBaseName(filename).substring(15).toLowerCase().startsWith("if")) {
|
||||
List<WARecord> wrs = new ArrayList<>();
|
||||
bandMap = new LinkedHashMap<>();
|
||||
|
||||
try (Reader in = new FileReader(wavelengthTable)) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "Reading wavelengths from: " + filename);
|
||||
|
||||
Iterable<CSVRecord> records = CSVFormat.DEFAULT.parse(in);
|
||||
for (CSVRecord record : records) {
|
||||
detector.add(Integer.parseInt(record.get(0).trim()));
|
||||
int detector = Integer.parseInt(record.get(0).trim());
|
||||
int band = Integer.parseInt(record.get(1).trim());
|
||||
double wavelength = Double.valueOf(record.get(2).trim());
|
||||
double fwhm = Double.valueOf(record.get(3).trim());
|
||||
int badBand = Integer.parseInt(record.get(4).trim());
|
||||
wrs.add(new WARecord(detector, band, wavelength, fwhm, badBand));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING, "Cannot read wavelength file "
|
||||
+ wavelengthTable.substring(wavelengthTable.lastIndexOf('\\') + 1));
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < wrs.size(); i++) {
|
||||
bandMap.put(i, wrs.get(i).getWavelength());
|
||||
}
|
||||
} else {
|
||||
// summary product routine, drop down list instead of sliders
|
||||
// need to work around bandMap routines
|
||||
bandMapSU = new LinkedHashMap<Integer, String>();
|
||||
for (int i = 0; i < bandNames.size(); i++) {
|
||||
bandMapSU.put(i, bandNames.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<Integer> getBandIndices() {
|
||||
|
||||
if (bandMapSU == null)
|
||||
return super.getBandIndices();
|
||||
else
|
||||
return new ArrayList<Integer>(bandMapSU.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void create() {
|
||||
if ((imgLabel != null) && imgLabel.isValidLabel()) {
|
||||
PDSObject imgObj = imgLabel.findObject("IMAGE");
|
||||
if (imgObj != null) {
|
||||
createImage(imgFilename, imgObj);
|
||||
}
|
||||
|
||||
PDSObject mapObj = imgLabel.findObject("IMAGE_MAP_PROJECTION");
|
||||
if (mapObj != null) {
|
||||
maxLat = mapObj.getDouble("MAXIMUM_LATITUDE");
|
||||
minLat = mapObj.getDouble("MINIMUM_LATITUDE");
|
||||
westLon = mapObj.getDouble("WESTERNMOST_LONGITUDE");
|
||||
eastLon = mapObj.getDouble("EASTERNMOST_LONGITUDE");
|
||||
minLine = mapObj.getInt("LINE_FIRST_PIXEL");
|
||||
maxLine = mapObj.getInt("LINE_LAST_PIXEL");
|
||||
minSample = mapObj.getInt("SAMPLE_FIRST_PIXEL");
|
||||
maxSample = mapObj.getInt("SAMPLE_LAST_PIXEL");
|
||||
|
||||
haveMapBounds = true;
|
||||
}
|
||||
|
||||
if (haveMapBounds) {
|
||||
lat = new double[maxLine][maxSample];
|
||||
lon = new double[maxLine][maxSample];
|
||||
|
||||
if (mapObj != null) {
|
||||
double degreesPerPixel = 1 / mapObj.getDouble("MAP_RESOLUTION");
|
||||
|
||||
for (int row = minLine; row < maxLine; row++) {
|
||||
for (int col = minSample; col < maxSample; col++) {
|
||||
lat[row][col] = minLat + (row - minLine) * degreesPerPixel;
|
||||
lon[row][col] = westLon + (col - minSample) * degreesPerPixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
51
src/main/java/reader/DDR.java
Normal file
51
src/main/java/reader/DDR.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package reader;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import util.JCATLog;
|
||||
|
||||
public class DDR extends CRISMPDSImageFirstGen {
|
||||
|
||||
public DDR(String filename) {
|
||||
super(filename);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating DDR object");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void create() {
|
||||
super.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumBands() {
|
||||
return bandCount;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String basename = "hrl0002422e_07_de182l_ddr1";
|
||||
|
||||
String filename = basename + ".img";
|
||||
DDR image = new DDR(filename);
|
||||
|
||||
System.out.printf("file %s\nwidth %d height %d numBands %d\n", filename, image.getWidth(),
|
||||
image.getHeight(), image.getNumBands());
|
||||
|
||||
// for (int i = 0; i < image.getNumBands(); i++)
|
||||
// System.out.printf("band %d %s\n", i, image.bandNames.get(i));
|
||||
|
||||
int band = 9;// elevation
|
||||
System.out.printf("Plotting %s\n", image.bandNames.get(band));
|
||||
BufferedImage bi = image.getQuickMonoImage(band);
|
||||
try {
|
||||
ImageIO.write(bi, "JPEG", new FileOutputStream(basename + ".jpg"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
51
src/main/java/reader/MRDR.java
Normal file
51
src/main/java/reader/MRDR.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package reader;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import util.JCATLog;
|
||||
|
||||
public class MRDR extends CRISMPDSImageNextGen {
|
||||
|
||||
public MRDR(String filename, String wavelengthTable) {
|
||||
super(filename, wavelengthTable);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating MRDR object");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String basename = "t1463_mrrif_35n063_0256_3";
|
||||
|
||||
String filename = basename + ".img";
|
||||
String wavelengthTable = basename.replaceAll("if", "wv") + ".tab";
|
||||
MRDR image = new MRDR(filename, wavelengthTable);
|
||||
|
||||
System.out.printf("file %s\nwidth %d height %d numBands %d\n", filename, image.getWidth(),
|
||||
image.getHeight(), image.getNumBands());
|
||||
|
||||
int x = 100;
|
||||
int y = 100;
|
||||
List<Double> wavelengths = image.getWavelengths();
|
||||
for (int i = 0; i < wavelengths.size(); i++) {
|
||||
double wavelength = wavelengths.get(i);
|
||||
double intensity = image.getPCFloatValue(y, x, i);
|
||||
System.out.printf("%d %f %f\n", i, wavelength, intensity);
|
||||
}
|
||||
|
||||
int red = 25;
|
||||
int green = 48;
|
||||
int blue = 65;
|
||||
BufferedImage bi = image.getQuickColorImage(red, green, blue);
|
||||
try {
|
||||
ImageIO.write(bi, "JPEG", new FileOutputStream(basename + ".jpg"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
77
src/main/java/reader/MTRDR.java
Normal file
77
src/main/java/reader/MTRDR.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package reader;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import definition.PDS.PDSObject;
|
||||
import util.JCATLog;
|
||||
|
||||
public class MTRDR extends CRISMPDSImageNextGen {
|
||||
|
||||
public MTRDR(String filename, String wavelengthTable) {
|
||||
super(filename, wavelengthTable);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating MTRDR object");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void create() {
|
||||
super.create();
|
||||
|
||||
if (haveMapBounds) {
|
||||
lat = new double[maxLine][maxSample];
|
||||
lon = new double[maxLine][maxSample];
|
||||
|
||||
PDSObject mapObj = imgLabel.findObject("IMAGE_MAP_PROJECTION");
|
||||
if (mapObj != null) {
|
||||
double degreesPerPixel = 1 / mapObj.getDouble("MAP_RESOLUTION");
|
||||
|
||||
for (int row = minLine; row < maxLine; row++) {
|
||||
for (int col = minSample; col < maxSample; col++) {
|
||||
lat[row][col] = minLat + (row - minLine) * degreesPerPixel;
|
||||
lon[row][col] = westLon + (col - minSample) * degreesPerPixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String basename = "frt000251c0_07_if165j_mtr3";
|
||||
|
||||
String filename = basename + ".img";
|
||||
String wavelengthTable = basename.replaceAll("if", "wv") + ".tab";
|
||||
MTRDR image = new MTRDR(filename, wavelengthTable);
|
||||
|
||||
System.out.printf("file %s\nwidth %d height %d numBands %d\n", filename, image.getWidth(),
|
||||
image.getHeight(), image.getNumBands());
|
||||
|
||||
int x = 100;
|
||||
int y = 100;
|
||||
List<Integer> bandIndices = image.getBandIndices();
|
||||
List<Double> wavelengths = image.getWavelengths();
|
||||
for (int i = 0; i < wavelengths.size(); i++) {
|
||||
int bandIndex = bandIndices.get(i);
|
||||
double wavelength = wavelengths.get(i);
|
||||
double intensity = image.getPCFloatValue(y, x, bandIndex);
|
||||
System.out.printf("%d %d %f %f\n", i, bandIndex, wavelength, intensity);
|
||||
}
|
||||
|
||||
int red = 150;
|
||||
int green = 300;
|
||||
int blue = 400;
|
||||
|
||||
BufferedImage bi = image.getQuickColorImage(red, green, blue);
|
||||
try {
|
||||
ImageIO.write(bi, "JPEG", new FileOutputStream(basename + ".jpg"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
138
src/main/java/reader/SWCDRLibrary.java
Normal file
138
src/main/java/reader/SWCDRLibrary.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package reader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import util.FileUtils;
|
||||
import util.JCATConfig;
|
||||
import util.JCATLog;
|
||||
import util.JCATMessageWindow;
|
||||
|
||||
public class SWCDRLibrary {
|
||||
|
||||
private NavigableMap<Integer, NavigableMap<Integer, String>> swMapS;
|
||||
private NavigableMap<Integer, NavigableMap<Integer, String>> swMapL;
|
||||
|
||||
private final String swPath = "/resources/sw";
|
||||
|
||||
private static SWCDRLibrary instance = null;
|
||||
|
||||
public static SWCDRLibrary getInstance() {
|
||||
if (instance == null)
|
||||
instance = new SWCDRLibrary();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private SWCDRLibrary() {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating SWCDRLibrary object");
|
||||
try {
|
||||
readResources();
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
JCATMessageWindow.show(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public LinkedHashMap<Integer, Double> getBandMap(String detector, int partition, double sclk) {
|
||||
NavigableMap<Integer, NavigableMap<Integer, String>> swMap = null;
|
||||
|
||||
if (detector.trim().equalsIgnoreCase("s"))
|
||||
swMap = swMapS;
|
||||
else if (detector.trim().equalsIgnoreCase("l"))
|
||||
swMap = swMapL;
|
||||
|
||||
Map.Entry<Integer, NavigableMap<Integer, String>> swEntry = swMap.floorEntry(partition);
|
||||
NavigableMap<Integer, String> partitionMap = swEntry.getValue();
|
||||
if (partitionMap == null)
|
||||
return null;
|
||||
|
||||
Map.Entry<Integer, String> partitionEntry = partitionMap.floorEntry((int) sclk);
|
||||
|
||||
String cdrFile = partitionEntry.getValue();
|
||||
if (cdrFile == null)
|
||||
return null;
|
||||
|
||||
// System.out.printf("Reading %s\n", FilenameUtils.getBaseName(cdrFile));
|
||||
|
||||
LinkedHashMap<Integer, Double> bandMap = new LinkedHashMap<>();
|
||||
try (Reader in = FileUtils.getInputStream(cdrFile)) {
|
||||
Iterable<CSVRecord> records = CSVFormat.DEFAULT.parse(in);
|
||||
int counter = (detector.trim().equalsIgnoreCase("l")) ? 0 : 1;
|
||||
for (CSVRecord record : records) {
|
||||
int band = Integer.parseInt(record.get(0).trim());
|
||||
double wavelength = Double.valueOf(record.get(1).trim());
|
||||
if (wavelength < 65535 || counter == 0) { // First line from SWCDR tab file is FillValue,
|
||||
// but important
|
||||
// to keep in, will be taken out later for gbBands
|
||||
bandMap.put(band, wavelength);
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return bandMap;
|
||||
}
|
||||
|
||||
private void readResources() throws URISyntaxException, IOException {
|
||||
swMapS = new TreeMap<>();
|
||||
swMapL = new TreeMap<>();
|
||||
|
||||
URI uri = this.getClass().getResource(swPath).toURI();
|
||||
Path myPath;
|
||||
|
||||
JCATConfig config = JCATConfig.getInstance();
|
||||
if (config.fromJar()) {
|
||||
myPath = config.getJarFileSystem().getPath(swPath);
|
||||
} else {
|
||||
myPath = Paths.get(uri);
|
||||
}
|
||||
|
||||
try (Stream<Path> walk = Files.walk(myPath, 1)) {
|
||||
for (Iterator<Path> it = walk.iterator(); it.hasNext();) {
|
||||
Path path = it.next();
|
||||
if (path.toString().endsWith("tab")) {
|
||||
String basename = FilenameUtils.getBaseName(path.toString());
|
||||
String[] parts = basename.split("_");
|
||||
int partition = Integer.parseInt(parts[1]);
|
||||
int sclk = Integer.parseInt(parts[2]);
|
||||
String detector = parts[4];
|
||||
|
||||
NavigableMap<Integer, NavigableMap<Integer, String>> swMap;
|
||||
if (detector.equalsIgnoreCase("s")) {
|
||||
swMap = swMapS;
|
||||
} else if (detector.equalsIgnoreCase("l")) {
|
||||
swMap = swMapL;
|
||||
} else
|
||||
continue;
|
||||
|
||||
NavigableMap<Integer, String> partitionMap = swMap.get(partition);
|
||||
if (partitionMap == null) {
|
||||
partitionMap = new TreeMap<>();
|
||||
swMap.put(partition, partitionMap);
|
||||
}
|
||||
|
||||
partitionMap.put(sclk, path.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
52
src/main/java/reader/TER.java
Normal file
52
src/main/java/reader/TER.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package reader;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import util.JCATLog;
|
||||
|
||||
public class TER extends CRISMPDSImageNextGen {
|
||||
|
||||
public TER(String filename, String wavelengthTable) {
|
||||
super(filename, wavelengthTable);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating TER object");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String basename = "hrl0002422e_07_if182j_ter3";
|
||||
|
||||
String filename = basename + ".img";
|
||||
String wavelengthTable = basename.replaceAll("if", "wv") + ".tab";
|
||||
TER image = new TER(filename, wavelengthTable);
|
||||
|
||||
System.out.printf("file %s\nwidth %d height %d numBands %d\n", filename, image.getWidth(),
|
||||
image.getHeight(), image.getNumBands());
|
||||
|
||||
int x = 100;
|
||||
int y = 100;
|
||||
List<Double> wavelengths = image.getWavelengths();
|
||||
for (int i = 0; i < wavelengths.size(); i++) {
|
||||
double wavelength = wavelengths.get(i);
|
||||
double intensity = image.getPCFloatValue(y, x, i);
|
||||
System.out.printf("%d %f %f\n", i, wavelength, intensity);
|
||||
}
|
||||
|
||||
int red = 150;
|
||||
int green = 300;
|
||||
int blue = 400;
|
||||
|
||||
BufferedImage bi = image.getQuickColorImage(red, green, blue);
|
||||
try {
|
||||
ImageIO.write(bi, "JPEG", new FileOutputStream(basename + ".jpg"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
169
src/main/java/reader/TRDR.java
Normal file
169
src/main/java/reader/TRDR.java
Normal file
@@ -0,0 +1,169 @@
|
||||
package reader;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import definition.PDS.PDSObject;
|
||||
import util.JCATLog;
|
||||
|
||||
public class TRDR extends CRISMPDSImageFirstGen {
|
||||
|
||||
private DDR ddr;
|
||||
|
||||
public TRDR(String filename) {
|
||||
this(filename, null);
|
||||
}
|
||||
|
||||
public TRDR(String filename, String ddrFilename) {
|
||||
super(filename);
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating TRDR object");
|
||||
|
||||
this.ddr = (new File(ddrFilename).exists() ? new DDR(ddrFilename) : null);
|
||||
|
||||
if (ddr != null) {
|
||||
int latIndex = ddr.findBandNumber("Latitude, areocentric, deg N");
|
||||
int lonIndex = ddr.findBandNumber("Longitude, areocentric, deg E");
|
||||
|
||||
lat = new double[(int) ddr.getHeight()][(int) ddr.getWidth()];
|
||||
lon = new double[(int) ddr.getHeight()][(int) ddr.getWidth()];
|
||||
|
||||
String sensor = imgLabel.getStringNoQuotes("MRO:SENSOR_ID").toLowerCase().trim();
|
||||
PDSObject fileObj = imgLabel.findObject("FILE");
|
||||
|
||||
if (fileObj == null)
|
||||
return;
|
||||
|
||||
PDSObject imgObj = fileObj.findObject("IMAGE");
|
||||
int bands = imgObj.getInt("BANDS");
|
||||
sensor = (sensor.equals("s")) ? Integer.toString(1) : sensor;
|
||||
sensor = (sensor.equals("l")) ? Integer.toString(0) : sensor;
|
||||
detector = (sensor.equals(Integer.toString(1)) || sensor.equals(Integer.toString(0)))
|
||||
? new ArrayList<Integer>(Collections.nCopies(bands, Integer.parseInt(sensor)))
|
||||
: null;
|
||||
|
||||
inaIndex = ddr.findBandNumber("INA at areoid, deg");
|
||||
|
||||
bc = Integer.parseInt(imgLabel.getStringNoQuotes("PIXEL_AVERAGING_WIDTH").trim());
|
||||
bc = (bc == 1) ? 0 : bc;
|
||||
bc = (bc == 10) ? 3 : bc;
|
||||
bc = (bc == 2) ? 1 : bc;
|
||||
bc = (bc == 5) ? 2 : bc;
|
||||
|
||||
wv = Integer.parseInt(imgLabel.getStringNoQuotes("MRO:WAVELENGTH_FILTER").trim());
|
||||
|
||||
String tick = imgLabel.getStringNoQuotes("SPACECRAFT_CLOCK_START_COUNT");
|
||||
int p = tick.indexOf("/");
|
||||
sclk = Integer.parseInt(tick.substring(p + 1, 11));
|
||||
|
||||
minLat = Double.MAX_VALUE;
|
||||
maxLat = -Double.MAX_VALUE;
|
||||
westLon = Double.MAX_VALUE;
|
||||
eastLon = -Double.MAX_VALUE;
|
||||
|
||||
for (int row = 0; row < ddr.getHeight(); row++) {
|
||||
for (int col = 0; col < ddr.getWidth(); col++) {
|
||||
float thisLat = ddr.getPCFloatValue(row, col, latIndex);
|
||||
if (thisLat < 32768) {
|
||||
maxLat = Math.max(maxLat, thisLat);
|
||||
minLat = Math.min(minLat, thisLat);
|
||||
lat[row][col] = thisLat;
|
||||
}
|
||||
|
||||
float thisLon = ddr.getPCFloatValue(row, col, lonIndex);
|
||||
if (thisLon < 32768) {
|
||||
eastLon = Math.max(eastLon, thisLon);
|
||||
westLon = Math.min(westLon, thisLon);
|
||||
lon[row][col] = thisLon;
|
||||
// check if we're crossing the 0 degree line
|
||||
if (eastLon - westLon > 180) {
|
||||
double tmp = eastLon;
|
||||
eastLon = westLon;
|
||||
westLon = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// int x = 100;
|
||||
// int y = 100;
|
||||
// for (int band = 0; band < ddr.getNumBands(); band++) {
|
||||
// System.out.printf("%s %f\n", ddr.bandNames.get(band),
|
||||
// ddr.getPCFloatValue(x, y, band));
|
||||
// }
|
||||
|
||||
haveMapBounds = true;
|
||||
} else {
|
||||
JCATLog.getInstance().getLogger().log(Level.WARNING,
|
||||
"Missing DDR file " + ddrFilename.substring(ddrFilename.lastIndexOf("\\") + 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean ddrExists() {
|
||||
return ddr != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void create() {
|
||||
super.create();
|
||||
|
||||
String startTime = imgLabel.getStringNoQuotes("SPACECRAFT_CLOCK_START_COUNT");
|
||||
if (startTime == null)
|
||||
throw new NullPointerException("No SPACECRAFT_CLOCK_START_COUNT in " + lblFilename);
|
||||
|
||||
String[] parts = startTime.split("/");
|
||||
int partition = Integer.parseInt(parts[0]);
|
||||
double sclk = Double.parseDouble(parts[1]);
|
||||
|
||||
String sensor = imgLabel.getStringNoQuotes("MRO:SENSOR_ID").toLowerCase();
|
||||
|
||||
// System.out.printf("SCLK %d/%10.0f sensor %s\n", partition, sclk,
|
||||
// sensor);
|
||||
|
||||
SWCDRLibrary swLib = SWCDRLibrary.getInstance();
|
||||
bandMap = swLib.getBandMap(sensor, partition, sclk);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String basename = "hrl0002422e_07_if182l_trr3";
|
||||
basename = "frt000063cb_07_if164s_trr3";
|
||||
|
||||
String filename = basename + ".img";
|
||||
TRDR image = new TRDR(filename);
|
||||
|
||||
System.out.printf("file %s\nwidth %d height %d numBands %d\n", filename, image.getWidth(),
|
||||
image.getHeight(), image.getNumBands());
|
||||
|
||||
int x = 100;
|
||||
int y = 100;
|
||||
List<Integer> bandIndices = image.getBandIndices();
|
||||
List<Double> wavelengths = image.getWavelengths();
|
||||
for (int i = 0; i < wavelengths.size(); i++) {
|
||||
int bandIndex = bandIndices.get(i);
|
||||
double wavelength = wavelengths.get(i);
|
||||
double intensity = image.getPCFloatValue(y, x, bandIndex);
|
||||
System.out.printf("%d %f %f\n", bandIndex, wavelength, intensity);
|
||||
}
|
||||
|
||||
int red = 25;
|
||||
int green = 48;
|
||||
int blue = 65;
|
||||
BufferedImage bi = image.getQuickColorImage(red, green, blue);
|
||||
try {
|
||||
ImageIO.write(bi, "JPEG", new FileOutputStream(basename + ".jpg"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
77
src/main/java/reader/WACDR.java
Normal file
77
src/main/java/reader/WACDR.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package reader;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import util.JCATLog;
|
||||
|
||||
/**
|
||||
* The WA level 4 CDR gives the actual center wavelength for each pixel, including smile.
|
||||
*
|
||||
* @author nairah1
|
||||
*
|
||||
*/
|
||||
public class WACDR extends CRISMPDSImageFirstGen {
|
||||
|
||||
public WACDR(String filename) {
|
||||
super(filename);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating WACDR object");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void create() {
|
||||
super.create();
|
||||
System.out.printf("%s: rowNumbers.size() = %d\n", lblFilename, rowNumbers.size());
|
||||
|
||||
if ((rowNumbers != null) && (imageWidth > 0)) {
|
||||
int i, j, size;
|
||||
size = rowNumbers.size();
|
||||
|
||||
bandMap = new LinkedHashMap<>();
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
double sum = 0;
|
||||
int count = 0;
|
||||
int midpt = (int) imageWidth / 2;
|
||||
int centerWidth = (int) (50 * imageWidth / 640.);
|
||||
for (j = midpt - centerWidth; j < midpt + centerWidth; j++) {
|
||||
double thisWavelength = getWavelengthFromFile(rowNumbers.get(i), j);
|
||||
|
||||
// if (j == 270) System.out.println("i, j, wave = "+i+",
|
||||
// "+j+", "+thisWavelength+", centerWidth = "+centerWidth);
|
||||
|
||||
if (thisWavelength > 1 && thisWavelength < 65535) {
|
||||
sum += thisWavelength;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
bandMap.put(size - i - 1, sum / count);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// retrieves the wavelength of a particular row number and
|
||||
// pixel column
|
||||
//
|
||||
protected double getWavelengthFromFile(int row, int col) {
|
||||
double result = -1.0;
|
||||
|
||||
if (rowNumbers != null) {
|
||||
int size = rowNumbers.size();
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
int rowNum = rowNumbers.get(i);
|
||||
if (rowNum == row) {
|
||||
result = getPCFloatValue(0, col, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
75
src/main/java/reader/WARecord.java
Normal file
75
src/main/java/reader/WARecord.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package reader;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import util.JCATLog;
|
||||
|
||||
public class WARecord implements Comparable<WARecord> {
|
||||
|
||||
private int detector;
|
||||
private int band;
|
||||
private double wavelength;
|
||||
private double fwhm;
|
||||
private int badBand;
|
||||
|
||||
/**
|
||||
* Spectrometer identifier; 0 = IR; 1 = VNIR
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getDetector() {
|
||||
return detector;
|
||||
}
|
||||
|
||||
/**
|
||||
* detector row number (0-479)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getBand() {
|
||||
return band;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard sampling center wavelength in nm
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getWavelength() {
|
||||
return wavelength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full Width Half Max in nm
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getFwhm() {
|
||||
return fwhm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bad Band Identifier; 0 = BAD; 1 = GOOD
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isBadBand() {
|
||||
return badBand == 0;
|
||||
}
|
||||
|
||||
public WARecord(int detector, int band, double wavelength, double fwhm, int badBand) {
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating WARecord object");
|
||||
this.detector = detector;
|
||||
this.band = band;
|
||||
this.wavelength = wavelength;
|
||||
this.fwhm = fwhm;
|
||||
this.badBand = badBand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(WARecord o) {
|
||||
return Double.compare(wavelength, o.wavelength);
|
||||
}
|
||||
|
||||
}
|
||||
17
src/main/java/util/AppVersion.java
Normal file
17
src/main/java/util/AppVersion.java
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
package util;
|
||||
|
||||
public class AppVersion {
|
||||
private static String gitRevision = new String("5da0c38");
|
||||
private static String applicationName = new String("JCAT");
|
||||
private static String dateString = new String("2021-Jul-11 13:12:44 EDT");
|
||||
|
||||
private AppVersion() {}
|
||||
|
||||
/**
|
||||
* version 5da0c38 (built 2021-Jul-11 13:12:44 EDT)
|
||||
*/
|
||||
public static String getVersionString() {
|
||||
return String.format("%s version %s (built %s)", applicationName, gitRevision, dateString);
|
||||
}
|
||||
}
|
||||
59
src/main/java/util/FileUtils.java
Normal file
59
src/main/java/util/FileUtils.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package util;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Vector;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
|
||||
public static boolean readAsciiFile(String filename, Vector<String> results) throws Exception {
|
||||
boolean result = false;
|
||||
|
||||
results.clear();
|
||||
|
||||
File f = new File(filename);
|
||||
if (f.exists()) {
|
||||
result = true;
|
||||
FileInputStream fileInput = new FileInputStream(filename);
|
||||
try (BufferedReader fileRdr = new BufferedReader(new InputStreamReader(fileInput))) {
|
||||
String s = fileRdr.readLine().trim();
|
||||
|
||||
while (s != null) {
|
||||
|
||||
results.add(s);
|
||||
|
||||
s = fileRdr.readLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String stripDoubleQuotes(String s) {
|
||||
StringBuilder r = new StringBuilder(s.length());
|
||||
r.setLength(s.length());
|
||||
int current = 0;
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char cur = s.charAt(i);
|
||||
if (cur != '"') r.setCharAt(current++, cur);
|
||||
}
|
||||
return r.toString();
|
||||
}
|
||||
|
||||
public static InputStreamReader getInputStream(String file) {
|
||||
JCATConfig config = JCATConfig.getInstance();
|
||||
InputStreamReader reader = null;
|
||||
try {
|
||||
if (config.fromJar()) {
|
||||
reader = new InputStreamReader(config.getClass().getResourceAsStream(file));
|
||||
} else {
|
||||
reader = new FileReader(file);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
JCATMessageWindow.show(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
}
|
||||
81
src/main/java/util/ImageUtils.java
Normal file
81
src/main/java/util/ImageUtils.java
Normal file
@@ -0,0 +1,81 @@
|
||||
package util;
|
||||
|
||||
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ImageUtils {
|
||||
|
||||
public enum STRETCH {
|
||||
LINEAR, GAUSSIAN
|
||||
}
|
||||
|
||||
/**
|
||||
* Get red, green, blue min and max values from the input image
|
||||
*
|
||||
* @param bi
|
||||
* @param type {@link STRETCH}
|
||||
* @param magnitude percent for linear, std dev for gaussian
|
||||
* @return
|
||||
*/
|
||||
public static List<Double> getStretchValues(BufferedImage bi, STRETCH type, double magnitude) {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINEST, "Entering method getStretchValues");
|
||||
int rgb;
|
||||
|
||||
DescriptiveStatistics r = new DescriptiveStatistics();
|
||||
DescriptiveStatistics g = new DescriptiveStatistics();
|
||||
DescriptiveStatistics b = new DescriptiveStatistics();
|
||||
|
||||
for (int i = 0; i < bi.getHeight(); i++) {
|
||||
for (int j = 0; j < bi.getWidth(); j++) {
|
||||
rgb = bi.getRGB(j, i);
|
||||
r.addValue((rgb >> 16) & 0x000000FF);
|
||||
g.addValue((rgb >> 8) & 0x000000FF);
|
||||
b.addValue((rgb) & 0x000000FF);
|
||||
}
|
||||
}
|
||||
double rMin, gMin, bMin;
|
||||
double rDiff, gDiff, bDiff;
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "Red stats: " + r);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "Green stats: " + g);
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, "Blue stats: " + b);
|
||||
|
||||
if (type == STRETCH.GAUSSIAN) {
|
||||
rMin = (int) (r.getMin() - magnitude * r.getStandardDeviation());
|
||||
gMin = (int) (g.getMin() - magnitude * g.getStandardDeviation());
|
||||
bMin = (int) (b.getMin() - magnitude * b.getStandardDeviation());
|
||||
|
||||
rDiff = (int) (2 * magnitude * r.getStandardDeviation());
|
||||
gDiff = (int) (2 * magnitude * g.getStandardDeviation());
|
||||
bDiff = (int) (2 * magnitude * b.getStandardDeviation());
|
||||
} else {
|
||||
if (magnitude == 0) {
|
||||
rMin = (int) r.getMin();
|
||||
gMin = (int) g.getMin();
|
||||
bMin = (int) b.getMin();
|
||||
rDiff = (int) (r.getMax() - r.getMin());
|
||||
gDiff = (int) (g.getMax() - g.getMin());
|
||||
bDiff = (int) (b.getMax() - b.getMin());
|
||||
} else {
|
||||
rMin = r.getPercentile(magnitude);
|
||||
gMin = g.getPercentile(magnitude);
|
||||
bMin = b.getPercentile(magnitude);
|
||||
rDiff = (r.getPercentile(100 - magnitude) - rMin);
|
||||
gDiff = (g.getPercentile(100 - magnitude) - gMin);
|
||||
bDiff = (b.getPercentile(100 - magnitude) - bMin);
|
||||
}
|
||||
}
|
||||
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, String.format("Setting red min, max to %f, %f", rMin, rDiff + rMin));
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, String.format("Setting green min, max to %f, %f", gMin, gDiff + gMin));
|
||||
JCATLog.getInstance().getLogger().log(Level.FINE, String.format("Setting blue min, max to %f, %f", bMin, bDiff + bMin));
|
||||
|
||||
return new ArrayList<>(Arrays.asList(rMin, gMin, bMin, rDiff, gDiff, bDiff));
|
||||
}
|
||||
|
||||
}
|
||||
123
src/main/java/util/JCATConfig.java
Normal file
123
src/main/java/util/JCATConfig.java
Normal file
@@ -0,0 +1,123 @@
|
||||
package util;
|
||||
|
||||
import org.apache.commons.configuration2.PropertiesConfiguration;
|
||||
import org.apache.commons.configuration2.PropertiesConfigurationLayout;
|
||||
import org.apache.commons.configuration2.builder.fluent.Configurations;
|
||||
import org.apache.commons.configuration2.ex.ConfigurationException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.util.Collections;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class JCATConfig {
|
||||
|
||||
private static JCATConfig instance = null;
|
||||
private final File configFile;
|
||||
private PropertiesConfiguration config;
|
||||
private boolean fromJar;
|
||||
private FileSystem jarFileSystem;
|
||||
|
||||
public static JCATConfig getInstance() {
|
||||
if (instance == null) instance = new JCATConfig();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public boolean fromJar() {
|
||||
return fromJar;
|
||||
}
|
||||
|
||||
public FileSystem getJarFileSystem() {
|
||||
return jarFileSystem;
|
||||
}
|
||||
|
||||
public File getLastWorkingDirectory() {
|
||||
String lastDir = config.getString("lastDirectory");
|
||||
if (lastDir == null) setLastDirectory(System.getProperty("user.home"));
|
||||
return new File(config.getString("lastDirectory"));
|
||||
}
|
||||
|
||||
public void setLastDirectory(String path) {
|
||||
config.setProperty("lastDirectory", path);
|
||||
}
|
||||
|
||||
private PropertiesConfiguration defaultConfiguration(File rootDir) {
|
||||
PropertiesConfiguration config = new PropertiesConfiguration();
|
||||
PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout();
|
||||
config.setLayout(layout);
|
||||
config.setProperty("blue", 41);
|
||||
layout.setComment("blue", "Index of blue band");
|
||||
config.setProperty("green", 122);
|
||||
layout.setComment("green", "Index of green band");
|
||||
config.setProperty("red", 304);
|
||||
layout.setComment("red", "Index of red band");
|
||||
config.setProperty("localArchive", rootDir.toString());
|
||||
layout.setComment("localArchive", "Path to local JCAT files");
|
||||
return config;
|
||||
}
|
||||
|
||||
private JCATConfig() {
|
||||
JCATLog.getInstance().getLogger().log(Level.FINER, "Instantiating JCATConfig object");
|
||||
Configurations configs = new Configurations();
|
||||
File rootDir = new File(System.getProperty("user.home"), "JCAT");
|
||||
if (!rootDir.isDirectory()) {
|
||||
if (!rootDir.mkdirs()) {
|
||||
System.err.println("Cannot create directory " + rootDir);
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
configFile = new File(rootDir, "config.txt");
|
||||
if (configFile.exists()) {
|
||||
try {
|
||||
config = configs.properties(configFile);
|
||||
} catch (ConfigurationException e) {
|
||||
JCATMessageWindow.show(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
config = defaultConfiguration(rootDir);
|
||||
save();
|
||||
}
|
||||
|
||||
try {
|
||||
URI uri = getClass().getResource("/resources").toURI();
|
||||
fromJar = uri.getScheme().equals("jar");
|
||||
if (fromJar) {
|
||||
jarFileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap());
|
||||
}
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
JCATMessageWindow.show(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public int getRed() {
|
||||
return config.getInt("red");
|
||||
}
|
||||
|
||||
public int getGreen() {
|
||||
return config.getInt("green");
|
||||
}
|
||||
|
||||
public int getBlue() {
|
||||
return config.getInt("blue");
|
||||
}
|
||||
|
||||
public String getLocalArchive() {
|
||||
return config.getString("localArchive");
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
config.write(new PrintWriter(configFile));
|
||||
} catch (ConfigurationException | IOException e) {
|
||||
JCATMessageWindow.show(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
63
src/main/java/util/JCATLog.java
Normal file
63
src/main/java/util/JCATLog.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package util;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class JCATLog {
|
||||
|
||||
|
||||
// Set logging level for JCAT (Level.SEVERE, Level.WARNING, Level.INFO, Level.CONFIG, Level.FINE,
|
||||
// Level.FINER, Level.FINEST)
|
||||
private static final Level loggingLevel = Level.FINER;
|
||||
|
||||
private static JCATLog instance = null;
|
||||
|
||||
private final Logger logger;
|
||||
private final LogRecordHandler handler;
|
||||
|
||||
private JCATLog() {
|
||||
|
||||
System.setProperty("java.util.logging.SimpleFormatter.format",
|
||||
"%1$tF %1$tT %4$s %2$s %5$s%6$s%n");
|
||||
logger = Logger.getGlobal();
|
||||
handler = new LogRecordHandler();
|
||||
logger.addHandler(handler);
|
||||
|
||||
logger.setLevel(loggingLevel);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static JCATLog getInstance() {
|
||||
|
||||
if (instance == null)
|
||||
instance = new JCATLog();
|
||||
|
||||
return instance;
|
||||
|
||||
}
|
||||
|
||||
public ArrayList<String> getLog(Level l) {
|
||||
|
||||
ArrayList<LogRecord> messages = handler.getMessages(l);
|
||||
ArrayList<String> toReturn = new ArrayList<>();
|
||||
|
||||
for (LogRecord a : messages)
|
||||
toReturn.add(
|
||||
String.format("%-23.23s\t%-30.30s\t%-15.15s\t%s", new Timestamp(a.getMillis()),
|
||||
a.getSourceClassName(), a.getLevel(), a.getMessage()));
|
||||
|
||||
return toReturn;
|
||||
|
||||
}
|
||||
|
||||
public Logger getLogger() {
|
||||
|
||||
return logger;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
31
src/main/java/util/JCATMessageWindow.java
Normal file
31
src/main/java/util/JCATMessageWindow.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package util;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
||||
public class JCATMessageWindow {
|
||||
|
||||
public static void show(Exception e) {
|
||||
TextArea textArea = new TextArea(ExceptionUtils.getStackTrace(e));
|
||||
textArea.setEditable(false);
|
||||
textArea.setWrapText(true);
|
||||
GridPane gridPane = new GridPane();
|
||||
gridPane.setMaxWidth(Double.MAX_VALUE);
|
||||
gridPane.add(textArea, 0, 0);
|
||||
|
||||
Alert alert = new Alert(AlertType.ERROR);
|
||||
alert.setHeaderText("An error occurred ... stack trace below:");
|
||||
alert.setTitle("Java Exception");
|
||||
alert.getDialogPane().setContent(gridPane);
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
public static void show(String s) {
|
||||
show(new RuntimeException(s));
|
||||
}
|
||||
|
||||
}
|
||||
58
src/main/java/util/LogRecordHandler.java
Normal file
58
src/main/java/util/LogRecordHandler.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package util;
|
||||
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogManager;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.StreamHandler;
|
||||
|
||||
public class LogRecordHandler extends StreamHandler {
|
||||
|
||||
private final ArrayList<LogRecord> messages;
|
||||
|
||||
public LogRecordHandler() {
|
||||
super();
|
||||
|
||||
messages = new ArrayList<>();
|
||||
|
||||
// write messages to stdout, not stderr
|
||||
LogManager.getLogManager().reset();
|
||||
setOutputStream(System.out);
|
||||
|
||||
}
|
||||
|
||||
public void publish(LogRecord record) {
|
||||
|
||||
if (record.getLevel() == Level.WARNING || record.getLevel() == Level.SEVERE) {
|
||||
Alert alert = new Alert(AlertType.INFORMATION);
|
||||
alert.setTitle("Error Message");
|
||||
alert.setHeaderText(null);
|
||||
alert.setContentText(record.getMessage());
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
messages.add(record);
|
||||
super.publish(record);
|
||||
flush();
|
||||
|
||||
}
|
||||
|
||||
public ArrayList<LogRecord> getMessages(Level l) {
|
||||
|
||||
ArrayList<LogRecord> toReturn = new ArrayList<>();
|
||||
int level = l.intValue();
|
||||
|
||||
for (LogRecord a : messages) {
|
||||
|
||||
if (a.getLevel().intValue() >= level) toReturn.add(a);
|
||||
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
65
src/main/java/util/RBmaker.java
Normal file
65
src/main/java/util/RBmaker.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package util;
|
||||
|
||||
public class RBmaker {
|
||||
|
||||
private final float[][][] bigarray;
|
||||
private final float[][] slope;
|
||||
private final float[][] yint;
|
||||
private final float[][] lowAnchor;
|
||||
private final double lowWave;
|
||||
public String img;
|
||||
|
||||
public RBmaker(String imgfile, float[][][] mappeddata, float y1, float y2, int kernel) {
|
||||
img = imgfile;
|
||||
bigarray = mappeddata;
|
||||
|
||||
arrayMedian Anchor = new arrayMedian(imgfile, bigarray, (int) y1, kernel);
|
||||
lowAnchor = Anchor.getToast();
|
||||
lowWave = Anchor.getWave();
|
||||
Anchor.resetArrayMedian(imgfile, bigarray, (int) y2, kernel);
|
||||
float[][] highAnchor = Anchor.getToast();
|
||||
double highWave = Anchor.getWave();
|
||||
|
||||
slope = new float[lowAnchor.length][lowAnchor[0].length];
|
||||
yint = new float[lowAnchor.length][lowAnchor[0].length];
|
||||
for (int i = 0; i < lowAnchor.length; i++) {
|
||||
for (int j = 0; j < lowAnchor[0].length; j++) {
|
||||
slope[i][j] = (highAnchor[i][j] - lowAnchor[i][j]) / (float) (highWave - lowWave);
|
||||
yint[i][j] = highAnchor[i][j] - ((float) highWave * slope[i][j]); // b = y - mx
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float[][] findNewRB(int wavelength, int kernel) {
|
||||
arrayMedian newRB = new arrayMedian(img, bigarray, wavelength, kernel);
|
||||
float[][] rArray = newRB.getToast();
|
||||
double wave = newRB.getWave();
|
||||
|
||||
float[][] rcArray = new float[rArray.length][rArray[0].length];
|
||||
float[][] rbArray = new float[rArray.length][rArray[0].length];
|
||||
for (int i = 0; i < rArray.length; i++) {
|
||||
for (int j = 0; j < rArray[0].length; j++) {
|
||||
rcArray[i][j] = (float) wave * slope[i][j] + yint[i][j];
|
||||
rbArray[i][j] = (rcArray[i][j] - rArray[i][j]) / Math.abs(rcArray[i][j]);
|
||||
}
|
||||
}
|
||||
return rbArray;
|
||||
}
|
||||
|
||||
public float[][] findRRCratio(int wavelength, int kernel) {
|
||||
arrayMedian newRB = new arrayMedian(img, bigarray, wavelength, kernel);
|
||||
float[][] rArray = newRB.getToast();
|
||||
double wave = newRB.getWave();
|
||||
|
||||
float[][] rcArray = new float[rArray.length][rArray[0].length];
|
||||
float[][] ratio = new float[rArray.length][rArray[0].length];
|
||||
for (int i = 0; i < rArray.length; i++) {
|
||||
for (int j = 0; j < rArray[0].length; j++) {
|
||||
rcArray[i][j] = (float) (wave - lowWave) * slope[i][j] + lowAnchor[i][j];
|
||||
ratio[i][j] = rArray[i][j] / rcArray[i][j];
|
||||
}
|
||||
}
|
||||
return ratio;
|
||||
}
|
||||
|
||||
}
|
||||
119
src/main/java/util/arrayMedian.java
Normal file
119
src/main/java/util/arrayMedian.java
Normal file
@@ -0,0 +1,119 @@
|
||||
package util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import reader.TRDR;
|
||||
|
||||
public class arrayMedian {
|
||||
|
||||
public float[][][] loaf;
|
||||
public float[][] toast;
|
||||
public float[][][] nextLoaf;
|
||||
public int medianIndex;
|
||||
public int medianSpan;
|
||||
public double realWave;
|
||||
|
||||
public arrayMedian(String imgfile, float[][][] array, int wave, int span) {
|
||||
String ddrFile = imgfile.replaceAll("if", "de").replaceAll("trr3", "ddr1");
|
||||
TRDR trdr_ = new TRDR(imgfile, ddrFile);
|
||||
List<Double> wavelength = trdr_.getWavelengths();
|
||||
|
||||
double distance = Math.abs(wavelength.get(0) - wave);
|
||||
int idx = 0;
|
||||
for (int c = 1; c < wavelength.size(); c++) {
|
||||
double cdistance = Math.abs(wavelength.get(c) - wave);
|
||||
if (cdistance < distance) {
|
||||
idx = c;
|
||||
distance = cdistance;
|
||||
}
|
||||
}
|
||||
medianIndex = idx;
|
||||
realWave = wavelength.get(medianIndex);
|
||||
|
||||
loaf = array;
|
||||
medianSpan = span;
|
||||
int h = loaf[0].length;
|
||||
int w = loaf[0][0].length;
|
||||
float[][][] slice = new float[h][w][medianSpan];
|
||||
int knife = (medianSpan - 1) / 2;
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
if (knife == 0) {
|
||||
slice[y][x][0] = loaf[medianIndex][y][x];
|
||||
} else {
|
||||
for (int z = medianIndex - knife; z <= medianIndex + knife; z++) {
|
||||
slice[y][x][z - (medianIndex - knife)] = loaf[z][y][x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toast = new float[h][w];
|
||||
nextLoaf = loaf;
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
Arrays.sort(slice[i][j]);
|
||||
int midindex = (slice[i][j].length - 1) / 2;
|
||||
toast[i][j] = slice[i][j][midindex];
|
||||
nextLoaf[medianIndex][i][j] = toast[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void resetArrayMedian(String imgfile, float[][][] array, int wave, int span) {
|
||||
String ddrFile = imgfile.replaceAll("if", "de").replaceAll("trr3", "ddr1");
|
||||
TRDR trdr_ = new TRDR(imgfile, ddrFile);
|
||||
List<Double> wavelength = trdr_.getWavelengths();
|
||||
|
||||
double distance = Math.abs(wavelength.get(0) - wave);
|
||||
int idx = 0;
|
||||
for (int c = 1; c < wavelength.size(); c++) {
|
||||
double cdistance = Math.abs(wavelength.get(c) - wave);
|
||||
if (cdistance < distance) {
|
||||
idx = c;
|
||||
distance = cdistance;
|
||||
}
|
||||
}
|
||||
medianIndex = idx;
|
||||
realWave = wavelength.get(idx);
|
||||
|
||||
loaf = array;
|
||||
medianSpan = span;
|
||||
int h = loaf[0].length;
|
||||
int w = loaf[0][0].length;
|
||||
float[][][] slice = new float[h][w][medianSpan];
|
||||
int knife = (medianSpan - 1) / 2;
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
if (knife == 0) {
|
||||
slice[y][x][0] = loaf[medianIndex][y][x];
|
||||
} else {
|
||||
for (int z = medianIndex - knife; z <= medianIndex + knife; z++) {
|
||||
slice[y][x][z - (medianIndex - knife)] = loaf[z][y][x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
toast = new float[h][w];
|
||||
nextLoaf = loaf;
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
Arrays.sort(slice[i][j]);
|
||||
int midindex = (slice[i][j].length - 1) / 2;
|
||||
toast[i][j] = slice[i][j][midindex];
|
||||
nextLoaf[medianIndex][i][j] = toast[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float[][] getToast() {
|
||||
return toast;
|
||||
}
|
||||
|
||||
public double getWave() {
|
||||
return realWave;
|
||||
}
|
||||
|
||||
}
|
||||
32
src/main/java/util/spBandDepth.java
Normal file
32
src/main/java/util/spBandDepth.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package util;
|
||||
|
||||
public class spBandDepth {
|
||||
|
||||
private final float[][] summaryProduct;
|
||||
|
||||
public spBandDepth(String imgfile, float[][][] mappeddata, int wav0, int ker0, int wav1, int ker1, int wav2, int ker2) {
|
||||
arrayMedian alpha = new arrayMedian(imgfile, mappeddata, wav0, ker0);
|
||||
float[][] sp1 = alpha.getToast();
|
||||
double wave1 = alpha.getWave();
|
||||
alpha.resetArrayMedian(imgfile, mappeddata, wav1, ker1);
|
||||
float[][] sp2 = alpha.getToast();
|
||||
double wave2 = alpha.getWave();
|
||||
alpha.resetArrayMedian(imgfile, mappeddata, wav2, ker2);
|
||||
float[][] sp3 = alpha.getToast();
|
||||
double wave3 = alpha.getWave();
|
||||
|
||||
float aVal = ((float) wave2 - (float) wave1) / ((float) wave3 - (float) wave1);
|
||||
float bVal = (float) 1 - aVal;
|
||||
|
||||
summaryProduct = new float[sp1.length][sp1[0].length];
|
||||
for (int i = 0; i < sp1.length; i++) {
|
||||
for (int j = 0; j < sp1[0].length; j++) {
|
||||
summaryProduct[i][j] = (float) 1 - sp2[i][j] / (aVal * sp3[i][j] + bVal * sp1[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float[][] getSummaryProduct() {
|
||||
return summaryProduct;
|
||||
}
|
||||
}
|
||||
32
src/main/java/util/spShoulder.java
Normal file
32
src/main/java/util/spShoulder.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package util;
|
||||
|
||||
public class spShoulder {
|
||||
|
||||
private final float[][] summaryProduct;
|
||||
|
||||
public spShoulder(String imgfile, float[][][] mappeddata, int wav0, int ker0, int wav1, int ker1, int wav2, int ker2) {
|
||||
arrayMedian alpha = new arrayMedian(imgfile, mappeddata, wav0, ker0);
|
||||
float[][] sp1 = alpha.getToast();
|
||||
double wave1 = alpha.getWave();
|
||||
alpha.resetArrayMedian(imgfile, mappeddata, wav1, ker1);
|
||||
float[][] sp2 = alpha.getToast();
|
||||
double wave2 = alpha.getWave();
|
||||
alpha.resetArrayMedian(imgfile, mappeddata, wav2, ker2);
|
||||
float[][] sp3 = alpha.getToast();
|
||||
double wave3 = alpha.getWave();
|
||||
|
||||
float aVal = ((float) wave2 - (float) wave1) / ((float) wave3 - (float) wave1);
|
||||
float bVal = (float) 1 - aVal;
|
||||
|
||||
summaryProduct = new float[sp1.length][sp1[0].length];
|
||||
for (int i = 0; i < sp1.length; i++) {
|
||||
for (int j = 0; j < sp1[0].length; j++) {
|
||||
summaryProduct[i][j] = (float) 1 - (bVal * sp1[i][j] + aVal * sp3[i][j]) / sp2[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float[][] getSummaryProduct() {
|
||||
return summaryProduct;
|
||||
}
|
||||
}
|
||||
BIN
src/main/resources/resources/JCAT_Tutorial.pdf
Normal file
BIN
src/main/resources/resources/JCAT_Tutorial.pdf
Normal file
Binary file not shown.
BIN
src/main/resources/resources/JCAT_Tutorial.pptx
Normal file
BIN
src/main/resources/resources/JCAT_Tutorial.pptx
Normal file
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS00L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0000000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 1 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC000061C4_01_IF254L_TRR2",
|
||||
"FFC000061C4_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS00L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS00L_6.IMG",439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 2560 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 439 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 640
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS00L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0000000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 1 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
SOURCE_PRODUCT_ID = {"FFC000061C4_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS00L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS00L_8.IMG", 439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 2560 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 1315 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 640
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS10L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0100000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 2 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC000061C4_01_IF254L_TRR2",
|
||||
"FFC000061C4_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS10L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS10L_6.IMG",439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 1280 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 439 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 320
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS10L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0100000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 2 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
SOURCE_PRODUCT_ID = {"FFC000061C4_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS10L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS10L_8.IMG", 439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 1280 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 1315 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 320
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS21L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0200010L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 5 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "1"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC000061C4_01_IF254L_TRR2",
|
||||
"FFC000061C4_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS21L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS21L_6.IMG", 56 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 512 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 56 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 128
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 55
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 55
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS21L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0200010L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 5 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "1"
|
||||
SOURCE_PRODUCT_ID = {"FFC000061C4_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS21L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS21L_8.IMG", 56 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 512 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 166 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 128
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 55
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 55
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS23L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0200030L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 5 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "3"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC000061C4_01_IF254L_TRR2",
|
||||
"FFC000061C4_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS23L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS23L_6.IMG", 63 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 512 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 63 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 128
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 62
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 62
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS23L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0200030L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 5 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "3"
|
||||
SOURCE_PRODUCT_ID = {"FFC000061C4_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS23L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS23L_8.IMG", 63 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 512 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 187 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 128
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 62
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 62
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS30L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0300000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 10 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC000061C4_01_IF254L_TRR2",
|
||||
"FFC000061C4_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS30L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS30L_6.IMG",439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 256 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 442 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 64
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS30L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0300000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 10 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
SOURCE_PRODUCT_ID = {"FFC000061C4_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS30L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS30L_8.IMG", 439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 256 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 1318 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 64
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS31L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0300010L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 10 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "1"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC000061C4_01_IF254L_TRR2",
|
||||
"FFC000061C4_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS31L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS31L_6.IMG", 56 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 256 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 56 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 64
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 55
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 55
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS31L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0300010L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 10 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "1"
|
||||
SOURCE_PRODUCT_ID = {"FFC000061C4_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS31L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS31L_8.IMG", 56 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 256 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 166 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 64
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 55
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 55
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS32L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0300020L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 10 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "2"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC000061C4_01_IF254L_TRR2",
|
||||
"FFC000061C4_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS32L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS32L_6.IMG", 71 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 256 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 71 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 64
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 70
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 70
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_061C4_VS32L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0300020L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 10 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "2"
|
||||
SOURCE_PRODUCT_ID = {"FFC000061C4_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 061C4. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_061C4_VS32L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_061C4_VS32L_8.IMG", 71 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 256 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 211 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 64
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 70
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 70
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS00L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0000000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 1 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC00006822_01_IF254L_TRR2",
|
||||
"FFC00006822_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS00L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS00L_6.IMG",439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 2560 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 439 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 640
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS00L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0000000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 1 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
SOURCE_PRODUCT_ID = {"FFC00006822_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS00L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS00L_8.IMG", 439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 2560 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 1315 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 640
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS10L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0100000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 2 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC00006822_01_IF254L_TRR2",
|
||||
"FFC00006822_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS10L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS10L_6.IMG",439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 1280 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 439 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 320
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS10L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0100000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 2 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
SOURCE_PRODUCT_ID = {"FFC00006822_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS10L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS10L_8.IMG", 439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 1280 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 1315 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 320
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS21L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0200010L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 5 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "1"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC00006822_01_IF254L_TRR2",
|
||||
"FFC00006822_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS21L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS21L_6.IMG", 56 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 512 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 56 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 128
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 55
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 55
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS21L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0200010L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 5 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "1"
|
||||
SOURCE_PRODUCT_ID = {"FFC00006822_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS21L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS21L_8.IMG", 56 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 512 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 166 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 128
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 55
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 55
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS23L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0200030L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 5 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "3"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC00006822_01_IF254L_TRR2",
|
||||
"FFC00006822_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS23L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS23L_6.IMG", 63 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 512 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 63 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 128
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 62
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 62
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS23L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0200030L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 5 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "3"
|
||||
SOURCE_PRODUCT_ID = {"FFC00006822_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS23L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS23L_8.IMG", 63 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 512 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 187 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 128
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 62
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 62
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS30L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0300000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 10 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC00006822_01_IF254L_TRR2",
|
||||
"FFC00006822_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS30L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS30L_6.IMG",439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 256 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 442 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 64
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS30L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "HYPERSPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0300000L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 10 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "0"
|
||||
SOURCE_PRODUCT_ID = {"FFC00006822_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS30L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS30L_8.IMG", 439 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 256 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 1318 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 64
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 438
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 438
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS31L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0300010L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 10 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "1"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC00006822_01_IF254L_TRR2",
|
||||
"FFC00006822_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS31L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS31L_6.IMG", 56 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 256 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 56 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 64
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 55
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 55
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,141 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format;
|
||||
2012-03-14 F.Morgan (APL) v8 TRR3,
|
||||
power law normalization for
|
||||
aerosol, artifact spectrum"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-4-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS31L_8"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2013-04-19T13:28:00.000
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "8"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0300010L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 10 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "1"
|
||||
SOURCE_PRODUCT_ID = {"FFC00006822_01_IF254L_TRR3"}
|
||||
|
||||
/* Atmospheric Transmission from Volcano Scan with artifact spectrum */
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
/* */
|
||||
/* This level 4 ADR contains 3 lines. The first line is the atmospheric */
|
||||
/* transmission spectrum at each binned detector column. Subsequent lines */
|
||||
/* are artifact spectra for each column; different lines correspond to */
|
||||
/* different pairs of scaling wavelengths as follows: */
|
||||
/* Line 2: [2007.0,1980.0], McGuire */
|
||||
/* Line 3: [2011.0,1899.0], Pelkey */
|
||||
/* */
|
||||
/* This VS ADR gives atmospheric transmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* */
|
||||
/* Atmospheric transmission is derived by dividing spectra from the base */
|
||||
/* (near 0 km elevation) by spectra from the summit (near 20 km elevation). */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. The raw */
|
||||
/* transmission is fit at wavelengths outside gas absorptions with an */
|
||||
/* aerosol model with optical depth quadratic in log wavelength, then */
|
||||
/* divided by that fit. */
|
||||
/* The detailed shape of the 2-micron CO2 absorption in CRISM depends on */
|
||||
/* pressure and temperature. The volcano scan derived transmision, */
|
||||
/* combining high and low elevation spectra, differs in detail from the */
|
||||
/* observed spectra being corrected. Atmospheric correction usually leaves */
|
||||
/* a broad bowl-shaped depression around 2 microns as a result of the */
|
||||
/* mismatch between scene and transmission spectra. A first order artifact */
|
||||
/* correction can be applied by adding a multiple of an artifact spectrum */
|
||||
/* from this ADR to the spectrum after initial correction. The artifact */
|
||||
/* spectrum included in this ADR is derived by correcting spectra from the */
|
||||
/* volcano scan base with the tranmsmission derived from the same volcano */
|
||||
/* scan - essentially, correcting the volcano scan with itself. A linear */
|
||||
/* interpolation between two wavelengths bracketing the 2-micron region */
|
||||
/* is assumed to define the correct continuum, and the difference between */
|
||||
/* continuum estimate and the actual correction is the artifact spectrum. */
|
||||
/* For these artifact spectra, the interpolation wavelengths were: */
|
||||
/* 1764.0,2239.0 nm */
|
||||
/* Use the artifact spectrum matching the scaling wavelengths used for */
|
||||
/* initial correction. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS31L_8.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS31L_8.IMG", 56 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 256 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 166 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 3
|
||||
LINE_SAMPLES = 64
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 55
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 55
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,114 @@
|
||||
PDS_VERSION_ID = PDS3
|
||||
LABEL_REVISION_NOTE = "2009-02-04 D. Humm (APL) v5 to
|
||||
go with v5 AT CDRs;
|
||||
2009-05-20 D. Humm (APL) still
|
||||
v5 but new filename format"
|
||||
|
||||
DATA_SET_ID = "MRO-M-CRISM-6-ADR-V1.0"
|
||||
PRODUCT_ID = "ADR10000000000_06822_VS32L_6"
|
||||
|
||||
/*( ADRptttttttttt_xxxxx_VSbwn_v )*/
|
||||
/*( p = partition at start of validity )*/
|
||||
/*( tttttttttt = sclk at start of validity )*/
|
||||
/*( xxxxx = obs. ID of volcano scan TRDR )*/
|
||||
/*( r = frame rate identifier, 0-4 )*/
|
||||
/*( b = binning identifier, 0-3 )*/
|
||||
/*( eee = exposure time parameter, 0-480 )*/
|
||||
/*( w = wavelength filter, 0-3 )*/
|
||||
/*( s = side: 1 or 2, or 0 if N/A )*/
|
||||
/*( n = sensor ID: S, L, or J )*/
|
||||
/*( v = version )*/
|
||||
|
||||
PRODUCT_TYPE = ADR
|
||||
INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
|
||||
SPACECRAFT_ID = MRO
|
||||
INSTRUMENT_NAME = "COMPACT RECONNAISSANCE IMAGING SPECTROMETER
|
||||
FOR MARS"
|
||||
INSTRUMENT_ID = CRISM
|
||||
TARGET_NAME = MARS
|
||||
START_TIME = 1980-01-01T00:00:00
|
||||
STOP_TIME = 2009-04-15T22:13:00
|
||||
SPACECRAFT_CLOCK_START_COUNT = "1/0000000000"
|
||||
SPACECRAFT_CLOCK_STOP_COUNT = "5/0924300802"
|
||||
OBSERVATION_TIME = NULL
|
||||
PRODUCT_CREATION_TIME = 2009-10-09T20:00:00
|
||||
|
||||
MRO:SENSOR_ID = "L"
|
||||
PRODUCT_VERSION_ID = "6"
|
||||
|
||||
SAMPLING_MODE_ID = "MULTISPEC"
|
||||
MRO:WAVELENGTH_FILE_NAME = "CDR410803692813_WA0300020L_3.IMG"
|
||||
PIXEL_AVERAGING_WIDTH = 10 /*( pixel bin size, across track ) */
|
||||
MRO:WAVELENGTH_FILTER = "2"
|
||||
|
||||
/* This ADR label describes one calibration data file. The file */
|
||||
/* is a mutiple-band, multiple-frame image file derived from flight data. */
|
||||
/* It consists of a binary image followed by a list of row numbers */
|
||||
/* corresponding to the wavelength filter. */
|
||||
|
||||
/* The VS or volcano scan ADR was calculated by Frank Morgan */
|
||||
/* of JHU/APL from CRISM observations of Olympus Mons. */
|
||||
|
||||
SOURCE_PRODUCT_ID = {
|
||||
"FFC00006822_01_IF254L_TRR2",
|
||||
"FFC00006822_03_IF254L_TRR2"
|
||||
}
|
||||
/* This VS ADR gives atmospheric tranmission derived from volcano scan */
|
||||
/* observation ID 06822. */
|
||||
/* It includes a spectral fit-based adjustment to correct an aerosol-like */
|
||||
/* slope at wavelengths shortward of approximately 2.7 microns. */
|
||||
/* The raw AT transmission is fit at wavelengths outside gas absorptions */
|
||||
/* with an aerosol model with optical depth quadratic in log wavelength. */
|
||||
/* The raw AT is divided by the fit to correct variable short wavelength */
|
||||
/* slopes. */
|
||||
|
||||
OBJECT = FILE
|
||||
^IMAGE = "ADR10000000000_06822_VS32L_6.IMG"
|
||||
|
||||
/* offset is in file records, which is just (imgbands*imglines) + 1 */
|
||||
^ROWNUM_TABLE = ("ADR10000000000_06822_VS32L_6.IMG", 71 )
|
||||
|
||||
RECORD_TYPE = FIXED_LENGTH
|
||||
RECORD_BYTES = 256 /* one row now, not one frame to save space in table */
|
||||
FILE_RECORDS = 71 /* compute by ROUND ((imgbands * imglines * */
|
||||
/* line_samples * samplebits/8 + */
|
||||
/* tablerows * tablerowbytes) / */
|
||||
/* record_bytes + 0.5 ) */
|
||||
OBJECT = IMAGE
|
||||
LINES = 1
|
||||
LINE_SAMPLES = 64
|
||||
SAMPLE_TYPE = PC_REAL
|
||||
SAMPLE_BITS = 32
|
||||
BANDS = 70
|
||||
BAND_NAME = NULL
|
||||
BAND_STORAGE_TYPE = LINE_INTERLEAVED
|
||||
DESCRIPTION = "Atmospheric transmission"
|
||||
END_OBJECT = IMAGE
|
||||
|
||||
/* be sure to pad this object to a full record (2560/bin bytes here) */
|
||||
OBJECT = ROWNUM_TABLE
|
||||
NAME = "SELECTED ROWS FROM DETECTOR"
|
||||
INTERCHANGE_FORMAT = "BINARY"
|
||||
ROWS = 70
|
||||
COLUMNS = 1
|
||||
ROW_BYTES = 2
|
||||
DESCRIPTION = "The detector is subsampled in the spectral direction
|
||||
by selecting specific rows to be downlinked. This
|
||||
table provides a list of the rows selected for all
|
||||
frames in this multidimensional image cube."
|
||||
|
||||
OBJECT = COLUMN
|
||||
NAME = DETECTOR_ROW_NUMBER
|
||||
DATA_TYPE = MSB_UNSIGNED_INTEGER
|
||||
BIT_MASK = 2#0000000111111111#
|
||||
START_BYTE = 1
|
||||
BYTES = 2
|
||||
DESCRIPTION = "Detector row number from which the data was taken."
|
||||
END_OBJECT = COLUMN
|
||||
|
||||
END_OBJECT = ROWNUM_TABLE
|
||||
|
||||
END_OBJECT = FILE
|
||||
|
||||
END
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user