agwx_biophys 0.0.1 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f9f340d516a0d61d5d391d7f346540c6af7e38e3
4
- data.tar.gz: 29dd22ef00cc3ec68b4a9aff760b7324fdb624a2
3
+ metadata.gz: 5f5b7941c684dc65e3369705c68acec24a292ee9
4
+ data.tar.gz: b311a850c49cdd1ee4e2a54c92fdf3449355f535
5
5
  SHA512:
6
- metadata.gz: 991e2c2afbeb889135e0c71344c2fdd6de0a53b339e969d5984c7f89d223b5ce41f8177c97afec6354e0b84adf8ce5b95a3ae9a5e579bf86ad5773ad3dbf6efc
7
- data.tar.gz: 8abb2837d359283f91762f624c31f63a1b94d7d559ee524b894cbda52db001b8a95ebe1199c29f353869d03029a0a82bf31b51490073bbe2550fa12999ceab85
6
+ metadata.gz: b582c22b9631410d8e3701f8fc90067759479cd5aa3e49462f5779d819435971a8d6e60b2a31da37155af13d6453abccf8497e3c2b05a8a9bbf816b32278b102
7
+ data.tar.gz: 24c2fa0c996dc09f659a30305824d01ca5f9959f4f3e9dadbd667e0b1cf9c27742b285554313a12e09ce7feebea71afad29cf02818d5d609c8d532e822644e49
data/.gitignore CHANGED
@@ -3,6 +3,8 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
+ .ruby-version
7
+ .ruby-gemset
6
8
  Gemfile.lock
7
9
  InstalledFiles
8
10
  _yardoc
@@ -20,4 +20,5 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "agwx_grids", ">= 0.0.4"
23
24
  end
@@ -0,0 +1,944 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #include <math.h>
5
+ #include <unistd.h>
6
+
7
+ #include <awsdir.h>
8
+ #include <awstime.h>
9
+ #include <awserror.h>
10
+ #include <grid/grid.h>
11
+
12
+
13
+ #ifndef M_PI
14
+ # define M_PI 3.14159265358979323846
15
+ #endif
16
+ #ifndef M_PI_2
17
+ # define M_PI_2 1.57079632679489661923
18
+ #endif
19
+ #ifndef M_1_PI
20
+ # define M_1_PI 0.31830988618379067154
21
+ #endif
22
+
23
+ #ifndef O_RDWR
24
+ # define O_RDWR 0000002 /* Open for reading or writing */
25
+ # define O_CREAT 0000400 /* Open with file create (uses third open arg) */
26
+ #endif
27
+
28
+ #define VIEW_RADIUS 1.2
29
+
30
+ #define DD_MAX_TEMP 86.0
31
+
32
+ float RectDD (float TMin, float TMax, float BaseTemp);
33
+ float RectAvgDD (float TAvg, float BaseTemp);
34
+ float ModBaseDD (float TMin, float TMax, float BaseTemp);
35
+ float ModBaseNoMaxDD (float TMin, float TMax, float BaseTemp);
36
+ float SineDD (float TMin, float TMax, float BaseTemp);
37
+ float p (float t);
38
+ float PdayDD (float TMin, float TMax);
39
+ Grid *CalcCumDD (char *prefix, int StartDoy,
40
+ int EndDoy, int Year, int Method, float BaseTemp,
41
+ int Subset, float xLowSub, float xHighSub, float yLowSub,
42
+ float yHighSub);
43
+
44
+ /*-------------------------------------------------------------------------
45
+ RectDD()
46
+ */
47
+ float
48
+ RectDD (float TMin, float TMax, float BaseTemp)
49
+ {
50
+ float dd;
51
+ dd = (TMin + TMax) / 2.0 - BaseTemp;
52
+ if (dd < 0.0)
53
+ {
54
+ dd = 0.0;
55
+ }
56
+ return dd;
57
+ }
58
+
59
+ /*-------------------------------------------------------------------------
60
+ RectAvgDD()
61
+ */
62
+ float
63
+ RectAvgDD (float TAvg, float BaseTemp)
64
+ {
65
+ float dd;
66
+ dd = TAvg - BaseTemp;
67
+ if (dd < 0.0)
68
+ {
69
+ dd = 0.0;
70
+ }
71
+ return dd;
72
+ }
73
+
74
+ /*-------------------------------------------------------------------------
75
+ ModBaseDD()
76
+ */
77
+ float
78
+ ModBaseDD (float TMin, float TMax, float BaseTemp)
79
+ {
80
+ if (TMin < BaseTemp)
81
+ TMin = BaseTemp;
82
+ if (TMax < BaseTemp)
83
+ TMax = BaseTemp;
84
+ if (TMin > DD_MAX_TEMP)
85
+ TMin = DD_MAX_TEMP;
86
+ if (TMax > DD_MAX_TEMP)
87
+ TMax = DD_MAX_TEMP;
88
+
89
+ return (TMin + TMax) / 2.0 - BaseTemp;
90
+ }
91
+
92
+ /*-------------------------------------------------------------------------
93
+ ModBaseNoMaxDD()
94
+ */
95
+ float
96
+ ModBaseNoMaxDD (float TMin, float TMax, float BaseTemp)
97
+ {
98
+ if (TMin < BaseTemp)
99
+ TMin = BaseTemp;
100
+ if (TMax < BaseTemp)
101
+ TMax = BaseTemp;
102
+
103
+ return (TMin + TMax) / 2.0 - BaseTemp;
104
+ }
105
+
106
+ /*-------------------------------------------------------------------------
107
+ SineDD()
108
+ */
109
+ float
110
+ SineDD (float TMin, float TMax, float BaseTemp)
111
+ {
112
+ float alpha;
113
+ float o1, o2;
114
+ float dd;
115
+ float avg;
116
+
117
+ /*-----------------------
118
+ * Source Degree-Days: The Calculation and Use
119
+ * of Heat Units in Pest management
120
+ */
121
+ if (TMin > TMax)
122
+ {
123
+ RegErr ("CalcDayDD:SineDD:", "", "Tmin > Tmax");
124
+ return -9999999;
125
+ }
126
+ if (TMin >= DD_MAX_TEMP)
127
+ {
128
+ return DD_MAX_TEMP - BaseTemp;
129
+ }
130
+ if (TMax <= BaseTemp)
131
+ {
132
+ return 0;
133
+ }
134
+ if (TMax <= DD_MAX_TEMP && TMin >= BaseTemp)
135
+ {
136
+ return (TMax + TMin) / 2 - BaseTemp;
137
+ }
138
+ alpha = (TMax - TMin) / 2;
139
+ avg = (TMax + TMin) / 2;
140
+
141
+ if (TMax <= DD_MAX_TEMP && TMin < BaseTemp)
142
+ {
143
+ o1 = asin ((BaseTemp - avg) / alpha);
144
+ return M_1_PI * ((avg - BaseTemp) * (M_PI_2 - o1) + alpha * cos (o1));
145
+ }
146
+ if (TMax > DD_MAX_TEMP && TMin >= BaseTemp)
147
+ {
148
+ o2 = asin ((DD_MAX_TEMP - avg) / alpha);
149
+ return M_1_PI * ((avg - BaseTemp) * (o2 + M_1_PI) +
150
+ (DD_MAX_TEMP - BaseTemp) * (M_PI_2 - o2) -
151
+ alpha * cos (o2));
152
+ }
153
+ if (TMax > DD_MAX_TEMP && TMin < BaseTemp)
154
+ {
155
+ o1 = asin ((BaseTemp - avg) / alpha);
156
+ o2 = asin ((DD_MAX_TEMP - avg) / alpha);
157
+ return M_1_PI * ((avg - BaseTemp) * (o2 - o1) +
158
+ alpha * (cos (o1) - cos (o2)) + (DD_MAX_TEMP -
159
+ BaseTemp) * (M_PI_2 -
160
+ o2));
161
+ }
162
+ }
163
+
164
+ /*-------------------------------------------------------------------------
165
+ p()
166
+ Function needed to calculate p-days, page B-81 of the PCM manual
167
+ */
168
+ float
169
+ p (float t)
170
+ {
171
+ t = (t - 32.) * 5. / 9.;
172
+ if (t < 7)
173
+ return 0.0;
174
+ if (t < 21)
175
+ return 10 * (1. - ((t - 21.) * (t - 21.)) / 196.);
176
+ if (t < 30)
177
+ return 10 * (1. - ((t - 21.) * (t - 21.)) / 81.);
178
+ return 0.0;
179
+ }
180
+
181
+ /*-------------------------------------------------------------------------
182
+ PdayDD()
183
+ P-day thermal time calculation
184
+ */
185
+ float
186
+ PdayDD (float TMin, float TMax)
187
+ {
188
+ return (1. / 24.) * (5 * p (TMin) + 8 * p (2 * TMin / 3 + TMax / 3) +
189
+ 8 * p (2 * TMax / 3 + TMin / 3) + 3 * p (TMax));
190
+ }
191
+
192
+ /*-------------------------------------------------------------------------
193
+ CalcCumDD()
194
+ Calculates cumulative DD between StartDoy & EndDoy using
195
+ Method and BaseTemp. Returns a grid with the cumDDs in
196
+ layer 1.
197
+ */
198
+ Grid *
199
+ CalcCumDD (char *prefix, int StartDoy,
200
+ int EndDoy, int Year, int Method, float BaseTemp,
201
+ int Subset, float xLowSub, float xHighSub, float yLowSub,
202
+ float yHighSub)
203
+ {
204
+
205
+ char Sub[40];
206
+
207
+ char buf[255];
208
+
209
+ char TMinFileName[255];
210
+ char TMaxFileName[255];
211
+ char TAvgFileName[255];
212
+ char GradCtlFile[100];
213
+ char GradDatFile[100];
214
+ char GridTmpFile[100];
215
+ char Date[100];
216
+ int fd;
217
+ FILE *fhctl;
218
+
219
+ Grid *pTMinG = NULL;
220
+ Grid *pTMaxG = NULL;
221
+ Grid *pTAvgG = NULL;
222
+ Grid *pDDG = NULL;
223
+ GridCursor *pTMinGC = NULL;
224
+ GridCursor *pTMaxGC = NULL;
225
+ GridCursor *pTAvgGC = NULL;
226
+ GLayer *pDDL = NULL;
227
+ GLView *pGLV = NULL;
228
+ GLayer *pGL = NULL;
229
+
230
+ float TMin;
231
+ float TMax;
232
+ float TAvg;
233
+ int TMinErr;
234
+ int TMaxErr;
235
+ int TAvgErr;
236
+ float DD;
237
+
238
+ int doy;
239
+ int earlydoy;
240
+
241
+ int srcdoy;
242
+ int TMinDoy, TMaxDoy, TAvgDoy;
243
+ float xPos, yPos;
244
+ int xIdx, yIdx;
245
+ float Val;
246
+ int FoundMin;
247
+ int FoundMax;
248
+ int FoundAvg;
249
+
250
+ int xNo, yNo;
251
+ int xNoSave, yNoSave;
252
+ float xLow, xHigh, yLow, yHigh;
253
+ int xStrt, xEnd, yStrt, yEnd;
254
+
255
+ float xIncr, yIncr, zIncr;
256
+ int lStrt, lEnd;
257
+ float BadValue;
258
+ int mnth, day;
259
+ int DecPlace;
260
+
261
+ int x, y, l;
262
+ int i, j;
263
+
264
+ float **CumDD = NULL;
265
+
266
+ strcpy (Sub, "CalcCumDD");
267
+
268
+
269
+
270
+ /*-------------------------------
271
+ * Generate Temperature Grid File Names
272
+ */
273
+ sprintf (TMinFileName, "%s/%sTMin%d", ASOS_GRID_DIR, prefix, Year);
274
+ sprintf (TMaxFileName, "%s/%sTMax%d", ASOS_GRID_DIR, prefix, Year);
275
+ sprintf (TAvgFileName, "%s/%sTAvg%d", ASOS_GRID_DIR, prefix, Year);
276
+ sprintf (GridTmpFile, "ddgrid.tmp");
277
+
278
+ /*------------------------------
279
+ * Load Grids and Create Cursors
280
+ */
281
+ if ((pTMinG = LoadGrid (TMinFileName)) == NULL)
282
+ {
283
+ RegErr (Sub, TMinFileName, "Couldn't Load Grid File");
284
+ goto ERROR;
285
+ }
286
+ if ((pTMinGC = CreateGridCursor (pTMinG)) == NULL)
287
+ {
288
+ RegErr (Sub, TMinFileName, "Couldn't Load Grid Cursor");
289
+ goto ERROR;
290
+ }
291
+
292
+ if ((pTMaxG = LoadGrid (TMaxFileName)) == NULL)
293
+ {
294
+ RegErr (Sub, TMaxFileName, "Couldn't Load Grid File");
295
+ goto ERROR;
296
+ }
297
+ if ((pTMaxGC = CreateGridCursor (pTMaxG)) == NULL)
298
+ {
299
+ RegErr (Sub, TMaxFileName, "Couldn't Load Grid Cursor");
300
+ goto ERROR;
301
+ }
302
+
303
+ if ((pTAvgG = LoadGrid (TAvgFileName)) == NULL)
304
+ {
305
+ RegErr (Sub, TAvgFileName, "Couldn't Load Grid File");
306
+ goto ERROR;
307
+ }
308
+ if ((pTAvgGC = CreateGridCursor (pTAvgG)) == NULL)
309
+ {
310
+ RegErr (Sub, TAvgFileName, "Couldn't Load Grid Cursor");
311
+ goto ERROR;
312
+ }
313
+
314
+
315
+ /*---------------------------------------
316
+ * Get the Dimensions of the temp grids
317
+ * (from TMAX; TMIN had better be the same)
318
+ */
319
+ xNo = GetGridXDim (pTMaxG);
320
+ yNo = GetGridYDim (pTMaxG);
321
+ xLow = GetGridXMin (pTMaxG);
322
+ xHigh = GetGridXMax (pTMaxG);
323
+ yLow = GetGridYMin (pTMaxG);
324
+ yHigh = GetGridYMax (pTMaxG);
325
+ lStrt = GetGridZMin (pTMaxG);
326
+ lEnd = GetGridZMax (pTMaxG);
327
+ xIncr = (xHigh - xLow) / (xNo - 1);
328
+ yIncr = (yHigh - yLow) / (yNo - 1);
329
+ BadValue = GetGridBadVal (pTMaxG);
330
+ DecPlace = GetGridDecPlace (pTMaxG);
331
+ xNoSave = xNo;
332
+ yNoSave = yNo;
333
+
334
+ /*---------------------------------------
335
+ * If this is a subset extraction then
336
+ * set limits.
337
+ */
338
+ if (Subset == TRUE)
339
+ {
340
+
341
+ /*----------------------
342
+ * Check for ridiculous values
343
+ if (xLowSub >= xHighSub) {
344
+ printf("error xLowSub %f >= xHighSub Value %f\n",xLowSub,
345
+ xHighSub);
346
+ goto ERROR;
347
+ }
348
+ if (xLowSub > xHigh) {
349
+ printf("Bad xLowSub Value %f \n",xLowSub);
350
+ goto ERROR;
351
+ }
352
+ if (xHighSub < xLow) {
353
+ printf("Bad xHighSub Value %f \n",xHighSub);
354
+ goto ERROR;
355
+ }
356
+
357
+ if (yLowSub >= yHighSub) {
358
+ printf("error yLowSub %f >= yHighSub Value %f\n",yLowSub,
359
+ yHighSub);
360
+ goto ERROR;
361
+ }
362
+ if (yLowSub > yHigh) {
363
+ printf("Bad yLowSub Value %f \n",yLowSub);
364
+ goto ERROR;
365
+ }
366
+ if (yHighSub < yLow) {
367
+ printf("Bad yHighSub Value %f \n",yHighSub);
368
+ goto ERROR;
369
+ }
370
+
371
+ /*----------------------
372
+ * Set to limits if exceeded
373
+ */
374
+ if (xLowSub < xLow)
375
+ xLowSub = xLow;
376
+ if (xHighSub > xHigh)
377
+ xHighSub = xHigh;
378
+ if (yLowSub < yLow)
379
+ yLowSub = yLow;
380
+ if (yHighSub > yHigh)
381
+ yHighSub = yHigh;
382
+
383
+ /*--------------------
384
+ * Find indices - All "rounding" is down when converting
385
+ * to integer. We check to see if it just (10% of the grid increment)
386
+ * misses a grid location
387
+ *
388
+ */
389
+ xStrt = (xLowSub - xLow) / xIncr;
390
+ if (xLowSub - (xIncr * xStrt + xLow) > xIncr * 0.1)
391
+ xStrt++;
392
+ xEnd = (xHighSub - xLow) / xIncr;
393
+ if ((xIncr * (xEnd + 1) + xLow - xHighSub) < xIncr * 0.1)
394
+ xEnd++;
395
+ yStrt = (yLowSub - yLow) / yIncr;
396
+ if (yLowSub - (yIncr * yStrt + yLow) > yIncr * 0.1)
397
+ yStrt++;
398
+ yEnd = (yHighSub - yLow) / yIncr;
399
+ if ((yIncr * (yEnd + 1) + yLow - yHighSub) < yIncr * 0.1)
400
+ yEnd++;
401
+ /* printf("Actual Limits Are %f %f %f and %f\n"
402
+ ,xStrt*xIncr+xLow,xEnd*xIncr+xLow
403
+ ,yStrt*yIncr+yLow,yEnd*yIncr+yLow); */
404
+ xHigh = xEnd * xIncr + xLow;
405
+ xLow = xStrt * xIncr + xLow;
406
+ xNo = xEnd - xStrt + 1;
407
+ yHigh = yEnd * yIncr + yLow;
408
+ yLow = yStrt * yIncr + yLow;
409
+ yNo = yEnd - yStrt + 1;
410
+
411
+ }
412
+ else
413
+ {
414
+ xStrt = 0;
415
+ xEnd = xNo - 1;
416
+ yStrt = 0;
417
+ yEnd = yNo - 1;
418
+ }
419
+
420
+ /*---------------------------------------
421
+ * Allocate temporary CumDD Array.
422
+ */
423
+ if ((CumDD = malloc (sizeof (float *) * xNoSave)) == NULL)
424
+ {
425
+ RegErr (Sub, "CumDD", AWSERR_MALLOC);
426
+ goto ERROR;
427
+ }
428
+ for (i = 0; i < xNoSave; i++)
429
+ {
430
+ CumDD[i] = NULL;
431
+ }
432
+ for (i = 0; i < xNoSave; i++)
433
+ {
434
+ if ((CumDD[i] = malloc (sizeof (float) * yNoSave)) == NULL)
435
+ {
436
+ RegErr (Sub, "CumDD sub", AWSERR_MALLOC);
437
+ goto ERROR;
438
+ }
439
+ for (j = 0; j < yNoSave; j++)
440
+ {
441
+ CumDD[i][j] = 0.0;
442
+ }
443
+ }
444
+
445
+ /*---------------------------------------
446
+ * Create the Output CumDD Grid with 1 layer.
447
+ */
448
+ zIncr = 1;
449
+ if ((pDDG = CreateGrid (GridTmpFile, xLow, xHigh, xNo, yLow, yHigh, yNo,
450
+ zIncr, BadValue, DecPlace)) == NULL)
451
+ {
452
+ RegErr (Sub, "", "Creating Temporary Grid");
453
+ goto ERROR;
454
+ }
455
+ if ((pDDL = CreateGLayer (pDDG, 1)) == NULL)
456
+ {
457
+ RegErr (Sub, "", "Creating Temporary Grid Layer");
458
+ goto ERROR;
459
+ }
460
+ if ((AddGLayer (pDDG, pDDL, FALSE)) != AWS_OK)
461
+ {
462
+ RegErr (Sub, "", "Adding Temporary Grid Layer");
463
+ goto ERROR;
464
+ }
465
+
466
+ /*===========================================================
467
+ * THE MAIN LOOP. For Each Day in the DD Calculation Range
468
+ */
469
+
470
+ for (doy = StartDoy; doy <= EndDoy; doy++)
471
+ {
472
+
473
+ /*----------------------------
474
+ * Set The Source TMin And TMax
475
+ * Cursors. If doy is not available
476
+ * Go back to doy-1 and onward to
477
+ * doy-5. If you go back past
478
+ * doy-5 then it is an error.
479
+ */
480
+ TMinDoy = doy;
481
+ earlydoy = doy - 5;
482
+ if (earlydoy < 1)
483
+ earlydoy = 1;
484
+
485
+ while (SetGCLayer (pTMinGC, TMinDoy) != AWS_OK)
486
+ {
487
+ if (TMinDoy <= earlydoy)
488
+ {
489
+ sprintf (buf, "Can Not Find a Layer between %d and %d",
490
+ earlydoy, doy);
491
+ RegErr (Sub, TMinFileName, buf);
492
+ goto ERROR;
493
+ }
494
+ TMinDoy--;
495
+ }
496
+
497
+ TMaxDoy = doy;
498
+ earlydoy = doy - 5;
499
+ if (earlydoy < 1)
500
+ earlydoy = 1;
501
+
502
+ while (SetGCLayer (pTMaxGC, TMaxDoy) != AWS_OK)
503
+ {
504
+ if (TMaxDoy <= earlydoy)
505
+ {
506
+ sprintf (buf, "Can Not Find a Layer between %d and %d",
507
+ earlydoy, doy);
508
+ RegErr (Sub, TMaxFileName, buf);
509
+ goto ERROR;
510
+ }
511
+ TMaxDoy--;
512
+ }
513
+
514
+ TAvgDoy = doy;
515
+ earlydoy = doy - 5;
516
+ if (earlydoy < 1)
517
+ earlydoy = 1;
518
+
519
+ while (SetGCLayer (pTAvgGC, TAvgDoy) != AWS_OK)
520
+ {
521
+ if (TAvgDoy <= earlydoy)
522
+ {
523
+ sprintf (buf, "Can Not Find a Layer between %d and %d",
524
+ earlydoy, doy);
525
+ RegErr (Sub, TAvgFileName, buf);
526
+ goto ERROR;
527
+ }
528
+ TAvgDoy--;
529
+ }
530
+
531
+ /*-------------------------------------------------
532
+ * With Source Days Set Now Loop Through All Locations
533
+ * on the Grid Layer
534
+ */
535
+ TMinErr = FirstGC (pTMinGC, &TMin);
536
+ TMaxErr = FirstGC (pTMaxGC, &TMax);
537
+ TAvgErr = FirstGC (pTAvgGC, &TAvg);
538
+ do
539
+ {
540
+ if (GetGCPos (pTMinGC, &xPos, &yPos) != AWS_OK)
541
+ {
542
+ RegErr (Sub, "", "Couldn't Get Position of the TMin Cursor");
543
+ goto ERROR;
544
+ }
545
+
546
+ /* Extract data only within requested limits */
547
+ if (GetGCPosIndex (pTMinGC, &xIdx, &yIdx) != AWS_OK)
548
+ {
549
+ RegErr (Sub, "",
550
+ "Couldn't Get Position Index of the TMin Cursor");
551
+ goto ERROR;
552
+ }
553
+ if (xIdx < xStrt || xIdx > xEnd || yIdx < yStrt || yIdx > yEnd)
554
+ {
555
+ continue;
556
+ }
557
+
558
+ /*----------------------
559
+ * If The Grid Position Has returned a bad value code
560
+ * we need to know if this an area that MICIS does not
561
+ * cover. We define that to be a location that has not had
562
+ * a value for 6 days. If a value at that location is
563
+ * found in the last 6 days then we take an average of the
564
+ * surounding area (defined by VIEW_RADIUS) if that returns a
565
+ * bad value, go to previous days. If you end up at the date
566
+ * of begining cumulation then Error.
567
+ *
568
+ * NOTE: the view area is a square. I use the term radius
569
+ * to suggest that the length is half way across.
570
+ */
571
+ FoundMin = TRUE;
572
+ if (TMinErr != AWS_OK)
573
+ {
574
+ FoundMin = FALSE;
575
+ srcdoy = TMinDoy;
576
+ earlydoy = TMinDoy - 5;
577
+ if (earlydoy < 1)
578
+ earlydoy = 1;
579
+ for (srcdoy = TMinDoy; srcdoy >= earlydoy; srcdoy--)
580
+ {
581
+ if ((pGL = GetGLayer (pTMinG, srcdoy)) != NULL)
582
+ {
583
+ if (GetGLVal (pTMinG, pGL, xPos, yPos, &Val) == AWS_OK)
584
+ {
585
+ FoundMin = TRUE;
586
+ break;
587
+ }
588
+ }
589
+ }
590
+ }
591
+ if ((FoundMin == TRUE) && (TMinErr != AWS_OK))
592
+ {
593
+ srcdoy = TMinDoy;
594
+ while (TMinErr != AWS_OK)
595
+ {
596
+ if ((pGLV = CreateGLView (pTMinG, srcdoy,
597
+ xPos - VIEW_RADIUS,
598
+ xPos + VIEW_RADIUS,
599
+ yPos - VIEW_RADIUS,
600
+ yPos + VIEW_RADIUS)) != NULL)
601
+ {
602
+ if ((TMinErr = AverageGLV (pGLV, &TMin)) != AWS_OK)
603
+ {
604
+ if (srcdoy <= 1)
605
+ {
606
+ sprintf (buf,
607
+ "Couldn't get tmin value for x=%f y=%f between %d and %d",
608
+ xPos, yPos, 1, doy);
609
+ RegErr (Sub, "", buf);
610
+ goto ERROR;
611
+ }
612
+ }
613
+ }
614
+ srcdoy--;
615
+ }
616
+ }
617
+ if (FoundMin == FALSE)
618
+ {
619
+ /*--------------------------
620
+ * Found is False for locations
621
+ * where Micis does not have coverage.
622
+ * Set these locations ot the BadValue code.
623
+ */
624
+ TMin = GetGridBadVal (pTMinG);
625
+ }
626
+
627
+ /*----------------------
628
+ * Now do the same for TMax if there
629
+ * was a problem.
630
+ */
631
+ if (GetGCPos (pTMaxGC, &xPos, &yPos) != AWS_OK)
632
+ {
633
+ RegErr (Sub, "", "Couldn't Get Position for TMax Cursor");
634
+ goto ERROR;
635
+ }
636
+ FoundMax = TRUE;
637
+ if (TMaxErr != AWS_OK)
638
+ {
639
+ FoundMax = FALSE;
640
+ srcdoy = TMaxDoy;
641
+ earlydoy = TMaxDoy - 5;
642
+ if (earlydoy < 1)
643
+ earlydoy = 1;
644
+ for (srcdoy = TMaxDoy; srcdoy >= earlydoy; srcdoy--)
645
+ {
646
+ if ((pGL = GetGLayer (pTMaxG, srcdoy)) != NULL)
647
+ {
648
+ if (GetGLVal (pTMaxG, pGL, xPos, yPos, &Val) == AWS_OK)
649
+ {
650
+ FoundMax = TRUE;
651
+ break;
652
+ }
653
+ }
654
+ }
655
+ }
656
+ if ((FoundMax == TRUE) && (TMaxErr != AWS_OK))
657
+ {
658
+ srcdoy = TMaxDoy;
659
+ while (TMaxErr != AWS_OK)
660
+ {
661
+ if ((pGLV = CreateGLView (pTMaxG, srcdoy,
662
+ xPos - VIEW_RADIUS,
663
+ xPos + VIEW_RADIUS,
664
+ yPos - VIEW_RADIUS,
665
+ yPos + VIEW_RADIUS)) != NULL)
666
+ {
667
+ if ((TMaxErr = AverageGLV (pGLV, &TMax)) != AWS_OK)
668
+ {
669
+ if (srcdoy <= 1)
670
+ {
671
+ sprintf (buf,
672
+ "Couldn't get tmax value for x=%f y=%f between %d and %d",
673
+ xPos, yPos, 1, doy);
674
+ RegErr (Sub, "", buf);
675
+ goto ERROR;
676
+ }
677
+ }
678
+ }
679
+ srcdoy--;
680
+ }
681
+ }
682
+ if (FoundMax == FALSE)
683
+ {
684
+ /*--------------------------
685
+ * Found is False for locations
686
+ * where Micis does not have coverage.
687
+ * Set these locations ot the BadValue code.
688
+ */
689
+ TMax = GetGridBadVal (pTMaxG);
690
+ }
691
+ /*----------------------
692
+ * Now do the same for TAvg if there
693
+ * was a problem.
694
+ */
695
+ if (GetGCPos (pTAvgGC, &xPos, &yPos) != AWS_OK)
696
+ {
697
+ RegErr (Sub, "", "Couldn't Get Position for TAvg Cursor");
698
+ goto ERROR;
699
+ }
700
+ FoundAvg = TRUE;
701
+ if (TAvgErr != AWS_OK)
702
+ {
703
+ FoundAvg = FALSE;
704
+ srcdoy = TAvgDoy;
705
+ earlydoy = TAvgDoy - 5;
706
+ if (earlydoy < 1)
707
+ earlydoy = 1;
708
+ for (srcdoy = TAvgDoy; srcdoy >= earlydoy; srcdoy--)
709
+ {
710
+ if ((pGL = GetGLayer (pTAvgG, srcdoy)) != NULL)
711
+ {
712
+ if (GetGLVal (pTAvgG, pGL, xPos, yPos, &Val) == AWS_OK)
713
+ {
714
+ FoundAvg = TRUE;
715
+ break;
716
+ }
717
+ }
718
+ }
719
+ }
720
+ if ((FoundAvg == TRUE) && (TAvgErr != AWS_OK))
721
+ {
722
+ srcdoy = TAvgDoy;
723
+ while (TAvgErr != AWS_OK)
724
+ {
725
+ if ((pGLV = CreateGLView (pTAvgG, srcdoy,
726
+ xPos - VIEW_RADIUS,
727
+ xPos + VIEW_RADIUS,
728
+ yPos - VIEW_RADIUS,
729
+ yPos + VIEW_RADIUS)) != NULL)
730
+ {
731
+ if ((TAvgErr = AverageGLV (pGLV, &TAvg)) != AWS_OK)
732
+ {
733
+ if (srcdoy <= 1)
734
+ {
735
+ sprintf (buf,
736
+ "Couldn't get tmax value for x=%f y=%f between %d and %d",
737
+ xPos, yPos, 1, doy);
738
+ RegErr (Sub, "", buf);
739
+ goto ERROR;
740
+ }
741
+ }
742
+ }
743
+ srcdoy--;
744
+ }
745
+ }
746
+ if (FoundAvg == FALSE)
747
+ {
748
+ /*--------------------------
749
+ * Found is False for locations
750
+ * where Micis does not have coverage.
751
+ * Set these locations ot the BadValue code.
752
+ */
753
+ TAvg = GetGridBadVal (pTAvgG);
754
+ }
755
+
756
+ if ((FoundMax == TRUE) && (FoundMin == TRUE) && (FoundAvg == TRUE))
757
+ {
758
+ /*-----------------------
759
+ * Convert from Celsius to Fahrenheit
760
+ */
761
+ TMax = TMax * 1.8 + 32.0;
762
+ TMin = TMin * 1.8 + 32.0;
763
+ TAvg = TAvg * 1.8 + 32.0;
764
+
765
+ /*------------------------
766
+ * Some times the grids get
767
+ * weird and the max is less than the min.
768
+ */
769
+ if (TMax < TMin)
770
+ {
771
+ Val = TMax;
772
+ TMax = TMin;
773
+ TMin = TMax;
774
+
775
+ }
776
+ /*-----------------------
777
+ * OK. Now we Have a Good
778
+ * TMin and TMax. Calculate DD
779
+ */
780
+ switch (Method)
781
+ {
782
+ case GRD_DD_RECTANGULAR:
783
+ DD = RectDD (TMin, TMax, BaseTemp);
784
+ break;
785
+ case GRD_DD_RECT_AVG:
786
+ DD = RectAvgDD (TAvg, BaseTemp);
787
+ break;
788
+ case GRD_DD_SINE_WAVE:
789
+ DD = SineDD (TMin, TMax, BaseTemp);
790
+ break;
791
+ case GRD_DD_MODIFIED_BASE:
792
+ DD = ModBaseDD (TMin, TMax, BaseTemp);
793
+ break;
794
+ case GRD_DD_PDAY:
795
+ DD = PdayDD (TMin, TMax);
796
+ break;
797
+ case GRD_DD_MODIFIED_BASE_NOMAX:
798
+ DD = ModBaseNoMaxDD (TMin, TMax, BaseTemp);
799
+ break;
800
+ }
801
+ }
802
+ else
803
+ {
804
+ DD = BadValue;
805
+ }
806
+
807
+ /*------------------------
808
+ * Add DD to cumulative sum at that location
809
+ */
810
+
811
+ if (DD != BadValue && CumDD[xIdx][yIdx] != BadValue)
812
+ {
813
+ CumDD[xIdx][yIdx] += DD;
814
+ }
815
+ else
816
+ {
817
+ CumDD[xIdx][yIdx] = BadValue;
818
+ }
819
+
820
+ }
821
+ while (((TMinErr = NextGC (pTMinGC, &TMin)) != AWS_ENDOFSTREAM)
822
+ && ((TMaxErr = NextGC (pTMaxGC, &TMax)) != AWS_ENDOFSTREAM)
823
+ && ((TAvgErr = NextGC (pTAvgGC, &TAvg)) != AWS_ENDOFSTREAM));
824
+
825
+ }
826
+ /*
827
+ * END OF DOY LOOP
828
+ *============================================================*/
829
+
830
+ /*-------------------------
831
+ Enter CumDD data into grid,
832
+ which may be a subset of the temp grids
833
+ */
834
+ yIdx = 0;
835
+ for (y = yStrt; y <= yEnd; y++)
836
+ {
837
+ xIdx = 0;
838
+ for (x = xStrt; x <= xEnd; x++)
839
+ {
840
+ if (PutGLValByIndex (pDDG, pDDL, xIdx, yIdx, CumDD[x][y]) != AWS_OK)
841
+ {
842
+ RegErr (Sub, "Error filling temporary CumDD grid", buf);
843
+ goto ERROR;
844
+ }
845
+ xIdx++;
846
+ }
847
+ yIdx++;
848
+ }
849
+
850
+ /*---------------------------
851
+ * Clean Up And Leave
852
+ */
853
+
854
+ if (pTMinG != NULL)
855
+ {
856
+ CloseGrid (pTMinG);
857
+ free (pTMinG);
858
+ pTMinG = NULL;
859
+ }
860
+ if (pTMaxG != NULL)
861
+ {
862
+ CloseGrid (pTMaxG);
863
+ free (pTMaxG);
864
+ pTMaxG = NULL;
865
+ }
866
+ if (pTAvgG != NULL)
867
+ {
868
+ CloseGrid (pTAvgG);
869
+ free (pTAvgG);
870
+ pTAvgG = NULL;
871
+ }
872
+ if (pTMinGC != NULL)
873
+ {
874
+ free (pTMinGC);
875
+ pTMinGC == NULL;
876
+ }
877
+ if (pTMaxGC != NULL)
878
+ {
879
+ free (pTMaxGC);
880
+ pTMaxGC == NULL;
881
+ }
882
+ if (pTAvgGC != NULL)
883
+ {
884
+ free (pTAvgGC);
885
+ pTAvgGC == NULL;
886
+ }
887
+
888
+ if (CumDD != NULL)
889
+ {
890
+ for (i = 0; i < xNoSave; i++)
891
+ {
892
+ free (CumDD[i]);
893
+ }
894
+ free (CumDD);
895
+ }
896
+
897
+ return pDDG;
898
+
899
+ ERROR:
900
+ if (pTMinG != NULL)
901
+ {
902
+ ClearGrid (pTMinG);
903
+ free (pTMinG);
904
+ pTMinG = NULL;
905
+ }
906
+ if (pTMaxG != NULL)
907
+ {
908
+ ClearGrid (pTMaxG);
909
+ free (pTMaxG);
910
+ pTMaxG = NULL;
911
+ }
912
+ if (pTAvgG != NULL)
913
+ {
914
+ ClearGrid (pTAvgG);
915
+ free (pTAvgG);
916
+ pTAvgG = NULL;
917
+ }
918
+ if (pTMinGC != NULL)
919
+ {
920
+ free (pTMinGC);
921
+ pTMinGC == NULL;
922
+ }
923
+ if (pTMaxGC != NULL)
924
+ {
925
+ free (pTMaxGC);
926
+ pTMaxGC == NULL;
927
+ }
928
+ if (pTAvgGC != NULL)
929
+ {
930
+ free (pTAvgGC);
931
+ pTAvgGC == NULL;
932
+ }
933
+
934
+ if (CumDD != NULL)
935
+ {
936
+ for (i = 0; i < xNoSave; i++)
937
+ {
938
+ free (CumDD[i]);
939
+ }
940
+ free (CumDD);
941
+ }
942
+
943
+ return NULL;
944
+ }