/* * Copyright (C) 1998 by Southwest Research Institute (SwRI) * * All rights reserved under U.S. Copyright Law and International Conventions. * * The development of this Software was supported by contracts NAG5-3148, * NAG5-6855, NAS8-36840, NAG5-2323, and NAG5-7043 issued on behalf of * the United States Government by its National Aeronautics and Space * Administration. Southwest Research Institute grants to the Government, * and others acting on its behalf, a paid-up nonexclusive, irrevocable, * worldwide license to reproduce, prepare derivative works, and perform * publicly and display publicly, by or on behalf of the Government. * Other than those rights granted to the United States Government, no part * of this Software may be reproduced in any form or by any means, electronic * or mechanical, including photocopying, without permission in writing from * Southwest Research Institute. All inquiries should be addressed to: * * Director of Contracts * Southwest Research Institute * P. O. Drawer 28510 * San Antonio, Texas 78228-0510 * * * Use of this Software is governed by the terms of the end user license * agreement, if any, which accompanies or is included with the Software * (the "License Agreement"). An end user will be unable to install any * Software that is accompanied by or includes a License Agreement, unless * the end user first agrees to the terms of the License Agreement. Except * as set forth in the applicable License Agreement, any further copying, * reproduction or distribution of this Software is expressly prohibited. * Installation assistance, product support and maintenance, if any, of the * Software is available from SwRI and/or the Third Party Providers, as the * case may be. * * Disclaimer of Warranty * * SOFTWARE IS WARRANTED, IF AT ALL, IN ACCORDANCE WITH THESE TERMS OF THE * LICENSE AGREEMENT. UNLESS OTHERWISE EXPLICITLY STATED, THIS SOFTWARE IS * PROVIDED "AS IS", IS EXPERIMENTAL, AND IS FOR NON-COMMERCIAL USE ONLY, * AND ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT * SUCH DISCLAIMERS ARE HELD TO BE LEGALLY INVALID. * * Limitation of Liability * * SwRI SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED AS A RESULT OF USING, * MODIFYING, CONTRIBUTING, COPYING, DISTRIBUTING, OR DOWNLOADING THIS * SOFTWARE. IN NO EVENT SHALL SwRI BE LIABLE FOR ANY INDIRECT, PUNITIVE, * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGE (INCLUDING LOSS OF BUSINESS, * REVENUE, PROFITS, USE, DATA OR OTHER ECONOMIC ADVANTAGE) HOWEVER IT ARISES, * WHETHER FOR BREACH OF IN TORT, EVEN IF SwRI HAS BEEN PREVIOUSLY ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. YOU HAVE SOLE RESPONSIBILITY FOR ADEQUATE * PROTECTION AND BACKUP OF DATA AND/OR EQUIPMENT USED IN CONNECTION WITH THE * SOFTWARE AND WILL NOT MAKE A CLAIM AGAINST SwRI FOR LOST DATA, RE-RUN TIME, * INACCURATE OUTPUT, WORK DELAYS OR LOST PROFITS RESULTING FROM THE USE OF * THIS SOFTWARE. YOU AGREE TO HOLD SwRI HARMLESS FROM, AND YOU COVENANT NOT * TO SUE SwRI FOR, ANY CLAIMS BASED ON USING THE SOFTWARE. * * Local Laws: Export Control * * You acknowledge and agree this Software is subject to the U.S. Export * Administration Laws and Regulations. Diversion of such Software contrary * to U.S. law is prohibited. You agree that none of the Software, nor any * direct product therefrom, is being or will be acquired for, shipped, * transferred, or reexported, directly or indirectly, to proscribed or * embargoed countries or their nationals, nor be used for nuclear activities, * chemical biological weapons, or missile projects unless authorized by U.S. * Government. Proscribed countries are set forth in the U.S. Export * Administration Regulations. Countries subject to U.S embargo are: Cuba, * Iran, Iraq, Libya, North Korea, Syria, and the Sudan. This list is subject * to change without further notice from SwRI, and you must comply with the * list as it exists in fact. You certify that you are not on the U.S. * Department of Commerce's Denied Persons List or affiliated lists or on the * U.S. Department of Treasury's Specially Designated Nationals List. You agree * to comply strictly with all U.S. export laws and assume sole responsibilities * for obtaining licenses to export or reexport as may be required. * * General * * These Terms represent the entire understanding relating to the use of the * Software and prevail over any prior or contemporaneous, conflicting or * additional, communications. SwRI can revise these Terms at any time * without notice by updating this posting. * * Trademarks * * The SwRI logo is a trademark of SwRI in the United States and other countries. * */ #ident "@(#) alloc_cdata.c 1.25 05/08/19 SwRI" #include #include #include "ret_codes.h" #include "user_defs.h" #include "gen_defs.h" #include "libtrec_idfs.h" /******************************************************************************* * * * IR_ALLOC_COLLAPSE_DATA SUBROUTINE * * * * DESCRIPTION * * This routine is called to allocate the memory that will be utilized to * * collapse over the necessary dimensions in order to produce the requested * * plots. The 4D data matrix is associated with collapsing over phi. The 3D * * will have one of two possible uses. If there are theta bins defined, it * * will be used to collapse over the THETA dimension. If there are no theta * * bins, it will hold the data for each individual sensor and be used to * * collapse over the ENERGY/FREQUENCY dimension (used to interleave). The 2D * * data matrix is associated with collapsing over energy/frequency ranges. * * If data is not be collapsed over phi, the delta_phi value passed to the * * routine ALLOC_COLLAPSE_INFO should be set to 360.0 This will result in * * one phi bin, which implies no collapsing. One bin status array is * * allocated to be used with the highest order data matrix utilized, with the * * highest starting at the 4D matrix. This status will indicate if data was * * ever placed into the sweep bins. * * * * INPUT VARIABLES * * None * * * * USAGE * * x = ir_alloc_collapse_data () * * * * NECESSARY SUBPROGRAMS * * sizeof () the size of the specified object in bytes * * malloc() allocates memory * * cos() returns double-precision cosine function of * * the argument * * sin() returns double-precision sine function of * * the argument * * abs() returns the absolute value of a number * * * * EXTERNAL VARIABLES * * struct general_info ginfo structure that holds information concerning * * the experiment that is being processed * * * * INTERNAL VARIABLES * * struct experiment_info *ex a pointer to the structure that holds * * specific experiment information * * struct collapse_data *cptr pointer to the collapse_data structure * * being processed * * struct bin_info *bptr a pointer to the structure that holds sweep * * binning information * * reg SDDAS_DOUBLE *phi_ptr pointer to the phi elements being processed * * reg SDDAS_DOUBLE *phi_low pointers to the lower and upper phi edges * * *phi_high * * reg SDDAS_DOUBLE *sin_ptr pointer to the sine of the center values * * reg SDDAS_DOUBLE *cos_ptr pointer to the cosine of the center values * * register SDDAS_FLOAT *dptr pointer to data matrix being initialized * * register SDDAS_FLOAT *frac pointer to the normalization array for the * * phi matrix * * register SDDAS_SHORT i looping variable * * reg SDDAS_CHAR *bin_stat pointer to the bin status array * * size_t bytes_4d number of bytes to allocate for collapsing * * 4-dimensional data * * size_t bytes_3d_binned number of bytes to allocate for collapsing * * 3-dimensional data * * size_t bytes_3d_separate number of bytes to allocate for collapsing * * 3-dimensional data * * size_t bytes_2d number of bytes to allocate for collapsing * * 2-dimensional data * * size_t bytes_bin the number of bytes to allocate for the * * bin status array * * size_t bytes_bands the number of bytes to allocate for the * * contiguous phi bands * * size_t bytes_rad the number of bytes to allocate for the * * contiguous phi bands in radians * * size_t bytes_centers the number of bytes to allocate for the * * phi centers, sine and cosine of centers * * size_t bytes the number of bytes to allocate * * size_t bytes_frac the number of bytes to allocate for the * * normalization factors for the phi bands * * size_t bytes_4d_per_buffer number of bytes needed per buffer for data * * size_t bytes_frac_per_buffer number of bytes needed per buffer for frac * * size_t bytes_double number of bytes needed for DOUBLE data type * * size_t num_bytes_sfloat the number of bytes needed for a SDDAS_FLOAT* * size_t num_bytes_sdouble number of bytes needed for a SDDAS_DOUBLE * * size_t num_bytes_schar number of bytes needed for a SDDAS_CHAR * * SDDAS_UINT base_size_bins variable used to hold common calculation * * for byte size determination * * SDDAS_UINT base_size_separate variable used to hold common calculation * * for byte size determination * * SDDAS_DOUBLE c_factor constant factor computed once used many * * SDDAS_FLOAT *stop_dptr loop termination variable * * SDDAS_FLOAT delta_bin value used to create the phi band values * * SDDAS_FLOAT *stop_fptr loop termination variable * * SDDAS_LONG offset indexing variable * * SDDAS_LONG num_ele no. of elements being processed * * SDDAS_SHORT num_theta_bins number of theta bins (may be one per sensor * * if no elevation constants) * * SDDAS_SHORT num_bins number of bins to be processed * * SDDAS_CHAR *base pointer to the memory being processed * * SDDAS_CHAR *stop_cptr loop termination variable * * char alloc_4d flag dictating if a 4D data matrix is needed* * void *tmp_ptr pointer which holds address passed back by * * the call to the MALLOC routine * * * * SUBSYSTEM * * Display Level * * * ******************************************************************************/ SDDAS_SHORT ir_alloc_collapse_data (void) { extern struct general_info ginfo; struct experiment_info *ex; struct collapse_data *cptr; struct bin_info *bptr; register SDDAS_DOUBLE *phi_ptr, *phi_low, *phi_high, *sin_ptr, *cos_ptr; register SDDAS_FLOAT *dptr, *frac; register SDDAS_SHORT i; register SDDAS_CHAR *bin_stat; size_t bytes_4d, bytes_3d_binned, bytes_3d_separate, bytes_2d, bytes_bin; size_t bytes_frac, bytes, bytes_rad, bytes_4d_per_buffer, bytes_frac_per_buffer; size_t bytes_double, bytes_bands, bytes_centers; SDDAS_UINT base_size_bins, base_size_separate; SDDAS_DOUBLE c_factor, *stop_dptr; SDDAS_FLOAT delta_bin, *stop_fptr; SDDAS_LONG offset, num_ele; SDDAS_SHORT num_theta_bins, num_bins; SDDAS_CHAR *base, *stop_cptr; char alloc_4d; void *tmp_ptr; /************************************************************************/ /* If the data matrices haven't already been allocated, do so at this */ /* time. Determine if the 4D data matrix is needed. The 3D and 2D */ /* data matrices are always needed. */ /************************************************************************/ ex = ginfo.expt; bptr = ex->bin_ptr; cptr = ex->collapse_ptr; if (cptr->base_data == NO_MEMORY) { size_t num_bytes_sfloat, num_bytes_sdouble, num_bytes_schar; /***********************************************************************/ /* If there are no defined theta bins, allocate one bin per sensor. */ /* Since set_collapse_info must be called before FILL_DATA and the */ /* user doesn't have to set up the bins, fill_data will use a fixed */ /* sweep so use swp_len for num_bins. */ /***********************************************************************/ num_bytes_sfloat = sizeof (SDDAS_FLOAT); num_bytes_sdouble = sizeof (SDDAS_DOUBLE); num_bytes_schar = sizeof (SDDAS_CHAR); num_bins = (ex->bin_ptr == NO_MEMORY) ? ex->swp_len : bptr->num_bins; num_theta_bins = (cptr->theta_bins == 0) ? ex->num_sensor : (SDDAS_SHORT) (abs (cptr->theta_bins)); alloc_4d = (cptr->phi_bins == 1) ? 0 : 1; base_size_bins = num_bins * num_theta_bins; base_size_separate = num_bins * ex->num_sensor; /***********************************************************************/ /* Allocate the number of bytes needed to hold all necessary data */ /* matrices. The size of the bin status array is based upon the */ /* highest order data matrix utilized. Since the status array is */ /* character and the data is float, divide by a factor of 4. */ /* If phi is being utilized, allocate space for the contiguous phi */ /* band values, phi centers and hold a phi data matrix PER buffer. */ /***********************************************************************/ if (!alloc_4d) bytes_4d = 0; /***********************************************************************/ /* Is there a "duplicate theta" issue? If so, phi data matrix */ /* allocates separate space per sensor, not per theta bin. */ /***********************************************************************/ else if (cptr->theta_bins < 0) bytes_4d = NUM_BUFFERS * base_size_separate * cptr->phi_bins * num_bytes_sfloat * cptr->num_units; else bytes_4d = NUM_BUFFERS * base_size_bins * cptr->phi_bins * num_bytes_sfloat * cptr->num_units; bytes_3d_binned = base_size_bins * num_bytes_sfloat * cptr->num_units; bytes_3d_separate = (cptr->theta_bins >= 0) ? 0 : base_size_separate * num_bytes_sfloat * cptr->num_units; bytes_2d = num_bins * num_bytes_sfloat * cptr->num_units; /***********************************************************************/ /* The tot_frac values are needed only for the PHI matrix since this */ /* data is acquired as the buffers are being filled. The 3D and 2D */ /* matrices must use the frac value returned with the data buffers. */ /***********************************************************************/ if (alloc_4d) { /***********************************************************************/ /* Is there a "duplicate theta" issue? If so, phi data matrix */ /* allocates separate space per sensor, not per theta bin. */ /***********************************************************************/ if (cptr->theta_bins < 0) { bytes_bin = NUM_BUFFERS * base_size_separate * cptr->phi_bins * num_bytes_schar * cptr->num_units; bytes_frac = NUM_BUFFERS * base_size_separate * cptr->phi_bins * num_bytes_sfloat * cptr->num_units; } else { bytes_bin = NUM_BUFFERS * base_size_bins * cptr->phi_bins * num_bytes_schar * cptr->num_units; bytes_frac = NUM_BUFFERS * base_size_bins * cptr->phi_bins * num_bytes_sfloat * cptr->num_units; } bytes_bands = (cptr->phi_bins + 1) * num_bytes_sfloat; bytes_rad = (cptr->phi_bins + 1) * num_bytes_sdouble; /* Need space for centers, sine of centers and cosine of centers. */ bytes_centers = 3 * cptr->phi_bins * num_bytes_sdouble; } else { /***********************************************************************/ /* Is there a "duplicate theta" issue? If so, save space for bin */ /* status per sensor, not per theta bin. */ /***********************************************************************/ if (cptr->theta_bins < 0) bytes_bin = base_size_separate * cptr->num_units * num_bytes_schar; else bytes_bin = base_size_bins * cptr->num_units * num_bytes_schar; bytes_frac = 0; bytes_bands = 0; bytes_rad = 0; bytes_centers = 0; } bytes = bytes_4d + bytes_3d_binned + bytes_3d_separate + bytes_2d + bytes_bin + bytes_frac + bytes_bands; if ((tmp_ptr = malloc (bytes)) == NO_MEMORY) return (COLLAPSE_DATA_MALLOC); cptr->base_data = tmp_ptr; base = (SDDAS_CHAR *) cptr->base_data; /***********************************************************************/ /* If phi is being utilized, allocate space for the contiguous phi */ /* band values in radians, phi centers, sine and cosine of phi */ /* centers. Due to compiler issues, needed to generate a separate */ /* malloc since pointer casting issues with DOUBLE data types. */ /***********************************************************************/ bytes_double = bytes_rad + bytes_centers; if (bytes_double > 0) { if ((tmp_ptr = malloc (bytes)) == NO_MEMORY) return (COLLAPSE_DATA_MALLOC); cptr->base_double = tmp_ptr; } /***********************************************************************/ /* Allocate space to hold the addresses of the pointers to the data */ /* and frac for the 4d phi matrices and for the bin stat values. */ /***********************************************************************/ bytes = (sizeof (SDDAS_FLOAT *) + sizeof (SDDAS_FLOAT *) + sizeof (SDDAS_CHAR *)) * NUM_BUFFERS; if ((tmp_ptr = malloc (bytes)) == NO_MEMORY) return (COLLAPSE_DATA_ADDRESS); cptr->base_4d = tmp_ptr; /* Cast base_4d to char * since void * and offset is in bytes. */ cptr->data_4d_ptr = (SDDAS_FLOAT **) ((SDDAS_CHAR *) cptr->base_4d); offset = NUM_BUFFERS * sizeof (SDDAS_FLOAT *); cptr->tot_frac_4d_ptr = (SDDAS_FLOAT **) ((SDDAS_CHAR *) cptr->base_4d + offset); offset += NUM_BUFFERS * sizeof (SDDAS_FLOAT *); cptr->bin_stat_ptr = (SDDAS_CHAR **) ((SDDAS_CHAR *) cptr->base_4d + offset); /***********************************************************************/ /* Initialize the data array for each DATA LEVEL (units) requested */ /* if the data matrix for averaging over PHI bins was allocated. */ /***********************************************************************/ if (alloc_4d) { offset = 0; bytes_4d_per_buffer = bytes_4d / NUM_BUFFERS; bytes_frac_per_buffer = bytes_frac / NUM_BUFFERS; num_ele = bytes_4d / (NUM_BUFFERS * num_bytes_sfloat); cptr->all_phi_elements = num_ele; for (i = 0; i < NUM_BUFFERS; ++i) { *(cptr->data_4d_ptr + i) = (SDDAS_FLOAT *) (base + offset); offset += bytes_4d_per_buffer; *(cptr->tot_frac_4d_ptr + i) = (SDDAS_FLOAT *) (base + offset); offset += bytes_frac_per_buffer; dptr = *(cptr->data_4d_ptr + i); frac = *(cptr->tot_frac_4d_ptr + i); stop_fptr = dptr + num_ele; for (; dptr < stop_fptr; ++dptr, ++frac) { *dptr = OUTSIDE_MIN; *frac = 0.0; } } /********************************************************************/ /* Create the contiguous phi bands. */ /********************************************************************/ cptr->phi_bands = (SDDAS_FLOAT *) (base + offset); dptr = cptr->phi_bands; stop_fptr = cptr->phi_bands + cptr->phi_bins; for (delta_bin = 0.0; dptr <= stop_fptr; ++dptr, delta_bin += cptr->delta_phi) *dptr = delta_bin; offset += (cptr->phi_bins + 1) * num_bytes_sfloat; /********************************************************************/ /* Convert the band values from degrees to radians. */ /********************************************************************/ cptr->phi_bands_rad = (SDDAS_DOUBLE *) cptr->base_double; phi_ptr = cptr->phi_bands_rad; dptr = cptr->phi_bands; stop_fptr = cptr->phi_bands + cptr->phi_bins; c_factor = M_PI / 180.0; for (; dptr <= stop_fptr; ++phi_ptr, ++dptr) *phi_ptr = *dptr * c_factor; /********************************************************************/ /* Compute the center values. */ /********************************************************************/ offset = (cptr->phi_bins + 1) * num_bytes_sdouble; cptr->phi_centers_rad = (SDDAS_DOUBLE *) ((SDDAS_CHAR *) cptr->base_double + offset); offset += cptr->phi_bins * num_bytes_sdouble; cptr->phi_sin_centers = (SDDAS_DOUBLE *) ((SDDAS_CHAR *) cptr->base_double + offset); offset += cptr->phi_bins * num_bytes_sdouble; cptr->phi_cos_centers = (SDDAS_DOUBLE *) ((SDDAS_CHAR *) cptr->base_double + offset); phi_ptr = cptr->phi_centers_rad; sin_ptr = cptr->phi_sin_centers; cos_ptr = cptr->phi_cos_centers; phi_low = &cptr->phi_bands_rad[0]; phi_high = &cptr->phi_bands_rad[1]; stop_dptr = cptr->phi_bands_rad + cptr->phi_bins; for (; phi_low < stop_dptr; ++phi_ptr, ++phi_low, ++phi_high, ++sin_ptr, ++cos_ptr) { *phi_ptr = (*phi_low + *phi_high) * 0.5; *sin_ptr = sin (*phi_ptr); *cos_ptr = cos (*phi_ptr); } } else { for (i = 0; i < NUM_BUFFERS; ++i) { *(cptr->data_4d_ptr + i) = NO_MEMORY; *(cptr->tot_frac_4d_ptr + i) = NO_MEMORY; } cptr->phi_bands = NO_MEMORY; cptr->phi_bands_rad = NO_MEMORY; cptr->phi_centers_rad = NO_MEMORY; cptr->phi_sin_centers = NO_MEMORY; cptr->phi_cos_centers = NO_MEMORY; cptr->all_phi_elements = 0; } /***********************************************************************/ /* Initialize the data array for each DATA LEVEL (units) requested */ /* for averaging over THETA bins. */ /***********************************************************************/ offset = bytes_4d + bytes_frac + bytes_bands; cptr->data_3d_binned = (SDDAS_FLOAT *) (base + offset); num_ele = bytes_3d_binned / num_bytes_sfloat; cptr->all_binned_theta_elements = num_ele; stop_fptr = cptr->data_3d_binned + num_ele; for (dptr = cptr->data_3d_binned; dptr < stop_fptr; ++dptr) *dptr = OUTSIDE_MIN; offset += bytes_3d_binned; /***********************************************************************/ /* Initialize the data array for each DATA LEVEL (units) requested */ /* for averaging over separated THETA bins (duplicate theta issue). */ /***********************************************************************/ if (bytes_3d_separate != 0) { cptr->data_3d_separate = (SDDAS_FLOAT *) (base + offset); num_ele = bytes_3d_separate / num_bytes_sfloat; cptr->all_separate_theta_elements = num_ele; stop_fptr = cptr->data_3d_separate + num_ele; for (dptr = cptr->data_3d_separate; dptr < stop_fptr; ++dptr) *dptr = OUTSIDE_MIN; offset += bytes_3d_separate; } /***********************************************************************/ /* Initialize the data array for each DATA LEVEL (units) requested. */ /***********************************************************************/ cptr->data_2d = (SDDAS_FLOAT *) (base + offset); stop_fptr = cptr->data_2d + bytes_2d / num_bytes_sfloat; for (dptr = cptr->data_2d; dptr < stop_fptr; ++dptr) *dptr = OUTSIDE_MIN; /***********************************************************************/ /* Initialize the bin status array for each DATA LEVEL requested. */ /***********************************************************************/ offset += bytes_2d; if (alloc_4d) { for (i = 0; i < NUM_BUFFERS; ++i) { *(cptr->bin_stat_ptr + i) = (SDDAS_CHAR *) (base + offset); offset += (bytes_bin / NUM_BUFFERS); bin_stat = *(cptr->bin_stat_ptr + i); stop_cptr = bin_stat + bytes_bin / (NUM_BUFFERS * num_bytes_schar); for (; bin_stat < stop_cptr; ++bin_stat) *bin_stat = 0; } } else { *(cptr->bin_stat_ptr + 0) = (SDDAS_CHAR *) (base + offset); bin_stat = *(cptr->bin_stat_ptr + 0); stop_cptr = bin_stat + bytes_bin / num_bytes_schar; for (; bin_stat < stop_cptr; ++bin_stat) *bin_stat = 0; for (i = 1; i < NUM_BUFFERS; ++i) *(cptr->bin_stat_ptr + i) = NO_MEMORY; } } return (ALL_OKAY); }