001    /**
002     * 
003     */
004    package org.wdssii.core;
005    
006    import java.util.Arrays;
007    import java.util.Date;
008    
009    /**
010     * @author lakshman
011     * 
012     */
013    public class PolarGrid extends DataType {
014            private final float elevation;
015    
016            private final float gateWidth;
017    
018            private final float beamWidth;
019    
020            private final float angularResolution;
021    
022            private final float nyquist;
023    
024            private final float rangeToFirstGate;
025            
026            private float[][] values;
027    
028            /**
029             * {@inheritDoc}
030             * @param master
031             */
032            public PolarGrid(PolarGrid master){
033                    super(master);
034                    this.elevation = master.elevation;
035                    this.gateWidth = master.gateWidth;
036                    this.beamWidth = master.beamWidth;
037                    this.angularResolution = master.angularResolution;
038                    this.nyquist = master.nyquist;
039                    this.rangeToFirstGate = master.rangeToFirstGate;
040                    this.values = copyOf(master.values);
041            }
042            
043            public float getBeamWidth() {
044                    return beamWidth;
045            }
046    
047            public float getNyquist() {
048                    return nyquist;
049            }
050    
051            public float getRangeToFirstGateKms(){
052                    return rangeToFirstGate;
053            }
054            
055            public float getAngularResolution() {
056                    return angularResolution;
057            }
058    
059            public float getElevation() {
060                    return elevation;
061            }
062    
063            public float getGateWidthKms() {
064                    return gateWidth;
065            }
066    
067            public float[][] getValues() {
068                    return values;
069            }
070    
071            /** creates a polar grid with all its values set to MissingData */
072            public PolarGrid(Location radarLocation, Date startTime, String typeName,
073                            float angularResolution, float radialResolution, float elevation,
074                            float beamWidth, float nyquist, float rangeToFirstGate, int numGates) {
075                    this(radarLocation, startTime, typeName, angularResolution,
076                                    radialResolution, elevation, beamWidth, nyquist,
077                                    rangeToFirstGate, numGates, MissingData);
078            }
079    
080            /**
081             * Creates a polar grid with the example provided, but with a new type name
082             * and separate copy of data
083             */
084            public PolarGrid(PolarGrid example, String typeName) {
085                    this(example.getLocation(), example.startTime, typeName,
086                                    example.angularResolution, example.gateWidth,
087                                    example.elevation, example.beamWidth, example.nyquist,
088                                    example.rangeToFirstGate,
089                                    example.getNumGates(), DataType.MissingData);
090            }
091    
092            /**
093             * Creates a polar grid with the example provided, but with a new type name
094             * and separate copy of data
095             */
096            public PolarGrid(PolarGrid example, String typeName, float elevation, float initValue) {
097                    this(example.getLocation(), example.startTime, typeName,
098                                    example.angularResolution, example.gateWidth,
099                                    elevation, example.beamWidth, example.nyquist,
100                                    example.rangeToFirstGate,
101                                    example.getNumGates(), initValue);
102            }
103            
104            /** creates a polar grid with all its values set to value passed in */
105            public PolarGrid(Location radarLocation, Date startTime, String typeName,
106                            float angularResolution, float radialResolution, float elevation,
107                            float beamWidth, float nyquist, float rangeToFirstGate, int numGates, float initValue) {
108                    super(radarLocation, startTime, typeName);
109                    this.angularResolution = angularResolution;
110                    int numAngles = (int) (360.0 / angularResolution + 0.001);
111                    this.elevation = elevation;
112                    this.gateWidth = radialResolution;
113                    this.beamWidth = beamWidth;
114                    this.nyquist = nyquist;
115                    this.rangeToFirstGate = rangeToFirstGate;
116                    this.values = new float[numAngles][numGates];
117                    for (int i = 0; i < numAngles; ++i) {
118                            Arrays.fill(values[i], initValue);
119                    }
120            }
121    
122            public PolarGrid(RadialSet rs, float angularResolutionDegrees,
123                            float radialResolution, int numGates, boolean projectToGround) {
124                    super(rs);
125                    this.angularResolution = angularResolutionDegrees;
126                    this.beamWidth = rs.getBeamWidth();
127                    int numAngles = (int) (360.0 / angularResolutionDegrees + 0.001);
128                    this.elevation = rs.getElevation();
129                    this.gateWidth = radialResolution;
130                    this.nyquist = rs.getNyquist();
131                    this.rangeToFirstGate = rs.getRangeToFirstGateKms();
132                    this.values = new float[numAngles][numGates];
133                    RadialSetLookup lookup = new RadialSetLookup(10, rs);
134    
135                    float range_correction = gateWidth / rs.getGateWidthKms();
136                    if (projectToGround) {
137                            // range along the beam at elev
138                            float elev_correction = (float) (1.0 / Math.cos(Math
139                                            .toRadians(elevation)));
140                            range_correction *= elev_correction;
141                    }
142    
143                    // get the correct values
144                    for (int i = 0; i < numAngles; i++) {
145                            float az = (i + 0.5f) * angularResolution; // mid-azimuth
146                            int radialno = lookup.getRadialNum(az);
147                            if (radialno >= 0) {
148                                    float[] radial = rs.getRadial(radialno).getValues();
149                                    for (int j = 0; j < numGates; j++) {
150                                            int gate = (int) Math.round(j * range_correction);
151                                            if (gate < radial.length)
152                                                    values[i][j] = radial[gate];
153                                    }
154                            }
155                    }
156    
157            }
158    
159            public int getNumRadials() {
160                    return values.length;
161            }
162    
163            public int getNumGates() {
164                    return values[0].length;
165            }
166    }