diff --git a/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.c b/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.c index 6dddc785e..68ad84941 100644 --- a/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.c +++ b/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.c @@ -6,6 +6,32 @@ #include "LibVCFNative.h" #include "tiledbvcf/tiledbvcf.h" +static int set_out_params_size_t( + JNIEnv* env, size_t value1, size_t value2, jlongArray valuesOut) { + jlong* c_values = (*env)->GetLongArrayElements(env, valuesOut, NULL); + if (c_values == NULL) { + return -1; + } + + // Check that an array of length 2 was passed. + if ((*env)->GetArrayLength(env, valuesOut) != 2) { + (*env)->ReleaseLongArrayElements(env, valuesOut, c_values, 0); + return -1; + } + + // Set the values in the result array. + c_values[0] = (jlong)value1; + c_values[1] = (jlong)value2; + + // Set the modified array back to the Java array. + (*env)->SetLongArrayRegion(env, valuesOut, 0, 2, c_values); + + // Release the array elements. + (*env)->ReleaseLongArrayElements(env, valuesOut, c_values, 0); + + return TILEDB_VCF_OK; +} + static int set_out_param_int32(JNIEnv* env, int32_t value, jintArray valueOut) { jint* c_value = (*env)->GetIntArrayElements(env, valueOut, NULL); if (c_value == NULL) { @@ -1083,3 +1109,40 @@ Java_io_tiledb_libvcfnative_LibVCFNative_tiledb_1vcf_1bed_1file_1get_1contig_1re return rc; } + +JNIEXPORT jint JNICALL +Java_io_tiledb_libvcfnative_LibVCFNative_tiledb_1vcf_1reader_1get_1variant_1stats_1buffer_1sizes( + JNIEnv* env, jclass self, jlong readerPtr, jlongArray resultsOut) { + (void)self; + tiledb_vcf_reader_t* reader = (tiledb_vcf_reader_t*)readerPtr; + if (reader == 0) { + return TILEDB_VCF_ERR; + } + + size_t num_rows; + size_t allele_size; + int32_t rc = tiledb_vcf_reader_get_variant_stats_buffer_sizes( + reader, &num_rows, &allele_size); + if (rc == TILEDB_VCF_OK) { + return set_out_params_size_t( + env, (size_t)num_rows, (size_t)allele_size, resultsOut); + } + + return rc; +} + +JNIEXPORT jint JNICALL +Java_io_tiledb_libvcfnative_LibVCFNative_tiledb_1vcf_1reader_1prepare_1variant_1stats( + JNIEnv* env, jclass self, jlong readerPtr) { + (void)self; + + tiledb_vcf_reader_t* reader = (tiledb_vcf_reader_t*)readerPtr; + + if (reader == 0) { + return TILEDB_VCF_ERR; + } + + int32_t rc = tiledb_vcf_reader_prepare_variant_stats(reader); + + return rc; +} diff --git a/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.h b/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.h index 070c75aa7..4002173a6 100644 --- a/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.h +++ b/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.h @@ -480,6 +480,41 @@ Java_io_tiledb_libvcfnative_LibVCFNative_tiledb_1vcf_1bed_1file_1get_1contig_1re jlongArray, jlongArray); +/* + * Class: io_tiledb_libvcfnative_LibVCFNative + * Method: tiledb_vcf_reader_get_variant_stats_buffer_sizes + * Signature: (J[J)I + */ +JNIEXPORT jint JNICALL +Java_io_tiledb_libvcfnative_LibVCFNative_tiledb_1vcf_1reader_1get_1variant_1stats_1buffer_1sizes( + JNIEnv*, jclass, jlong, jlongArray); + +/* + * Class: io_tiledb_libvcfnative_LibVCFNative + * Method: tiledb_vcf_reader_prepare_variant_stats + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_io_tiledb_libvcfnative_LibVCFNative_tiledb_1vcf_1reader_1prepare_1variant_1stats( + JNIEnv*, jclass, jlong); + +/* + * Class: io_tiledb_libvcfnative_LibVCFNative + * Method: tiledb_vcf_reader_read_from_variant_stats + * Signature: (J[J[B[J[I[I[F)I + */ +JNIEXPORT jint JNICALL +Java_io_tiledb_libvcfnative_LibVCFNative_tiledb_1vcf_1reader_1read_1from_1variant_1stats( + JNIEnv*, + jclass, + jlong, + jlongArray, + jbyteArray, + jlongArray, + jintArray, + jintArray, + jfloatArray); + #ifdef __cplusplus } #endif diff --git a/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.java b/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.java index 420afec02..9a20cafda 100644 --- a/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.java +++ b/apis/java/src/main/java/io/tiledb/libvcfnative/LibVCFNative.java @@ -171,4 +171,18 @@ public static final native int tiledb_vcf_bed_file_get_contig_region( byte[] region_contig, long[] region_start, long[] region_end); + + public static final native int tiledb_vcf_reader_get_variant_stats_buffer_sizes( + long readerPtr, long[] results); + + public static final native int tiledb_vcf_reader_prepare_variant_stats(long readerPtr); + + public static final native int tiledb_vcf_reader_read_from_variant_stats( + long readerPtr, + long[] pos, + byte[] allele, + long[] allele_offsets, + int[] ac, + int[] an, + float[] af); } diff --git a/apis/java/src/main/java/io/tiledb/libvcfnative/README.md b/apis/java/src/main/java/io/tiledb/libvcfnative/README.md index 947b7fd4d..354b69c7f 100644 --- a/apis/java/src/main/java/io/tiledb/libvcfnative/README.md +++ b/apis/java/src/main/java/io/tiledb/libvcfnative/README.md @@ -1,20 +1,30 @@ -The LibVCFNative bindings are produced with `javah`. +# The LibVCFNative bindings are produced with `javah`. -To build the binding you must first compile the java file to a class file: +## To build the LibVCFNative header run: +``` +javac -cp .:commons-io-2.14.0.jar *.java -h dstara +``` + +This will generate io_tiledb_libvcfnative_LibVCFNative.h as a separate file. +## Format the new header file: ``` -cd api/spark/src/main/java/io/tiledb/libvcfnative -javac LibVCFNative.java +clang-format -i io_tiledb_libvcfnative_LibVCFNative.h ``` -Next you can use `javah` to rebuild the LibVCFNative header: +## Replace the old header file with the new: ``` -# Navigate back to top level spark src directory -cd ../../../ -javah -v -cp $PWD -o io/tiledb/libvcfnative/LibVCFNative.h io.tiledb.libvcfnative.LibVCFNative +mv io_tiledb_libvcfnative_LibVCFNative.h LibVCFNative.h ``` -It is safe to delete the class file now: +## It is safe to delete the class files now: ``` -rm io/tiledb/libvcfnative/LibVCFNative.class +rm io/tiledb/libvcfnative/*.class ``` + + + + + + + diff --git a/apis/java/src/main/java/io/tiledb/libvcfnative/VCFReader.java b/apis/java/src/main/java/io/tiledb/libvcfnative/VCFReader.java index 4a9bfb0f8..3cb0c822f 100644 --- a/apis/java/src/main/java/io/tiledb/libvcfnative/VCFReader.java +++ b/apis/java/src/main/java/io/tiledb/libvcfnative/VCFReader.java @@ -584,6 +584,25 @@ public String stats() { return stats; } + public VCFReader prepareVariantStats() { + int rc = LibVCFNative.tiledb_vcf_reader_prepare_variant_stats(this.readerPtr); + if (rc != 0) { + String msg = getLastErrorMessage(); + throw new RuntimeException("Error preparing variant stats: " + msg); + } + return this; + } + + public long[] getVariantStatsBufferSizes() { + long[] results = new long[2]; + int rc = LibVCFNative.tiledb_vcf_reader_get_variant_stats_buffer_sizes(this.readerPtr, results); + if (rc != 0) { + String msg = getLastErrorMessage(); + throw new RuntimeException("Error getting variant stats buffer sizes: " + msg); + } + return results; + } + public String version() { return LibVCFNative.tiledb_vcf_version(); } diff --git a/apis/java/src/main/java/io/tiledb/libvcfnative/generateJNI.sh b/apis/java/src/main/java/io/tiledb/libvcfnative/generateJNI.sh new file mode 100644 index 000000000..5d89d6c1d --- /dev/null +++ b/apis/java/src/main/java/io/tiledb/libvcfnative/generateJNI.sh @@ -0,0 +1,4 @@ +javac - cp. : commons - io - 2.14.0.jar *.java - h.; +clang - format - i io_tiledb_libvcfnative_LibVCFNative.h; +mv io_tiledb_libvcfnative_LibVCFNative.h LibVCFNative.h; +rm*.class; diff --git a/apis/java/src/test/java/io/tiledb/libvcfnative/VCFReaderTest.java b/apis/java/src/test/java/io/tiledb/libvcfnative/VCFReaderTest.java index b1aceec36..0f212c572 100644 --- a/apis/java/src/test/java/io/tiledb/libvcfnative/VCFReaderTest.java +++ b/apis/java/src/test/java/io/tiledb/libvcfnative/VCFReaderTest.java @@ -378,6 +378,20 @@ public void testStats() throws IOException { Assert.assertNotNull(reader.stats()); } + @Test + public void testVariantStatsPrepare() throws IOException { + VCFReader reader = getVFCReader(Optional.empty(), Optional.of(constructBEDURI())); + reader.prepareVariantStats(); + } + + @Test + public void testVariantStatsBufferSizes() throws IOException { + VCFReader reader = getVFCReader(Optional.empty(), Optional.of(constructBEDURI())); + reader.prepareVariantStats(); + long[] a = reader.getVariantStatsBufferSizes(); + System.out.println(a[0] + " ---->>>>>>>> " + a[1]); + } + /** * * Checks that the reader attribute details are initialized in constructor *