source: trunk/MagicSoft/Mars/mbadpixels/MBadPixelsTreat.cc@ 5725

Last change on this file since 5725 was 5574, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 21.4 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Oscar Blanch 12/2001 <mailto:blanch@ifae.es>
19! Author(s): Thomas Bretz 08/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
20!
21! Copyright: MAGIC Software Development, 2000-2004
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28// MBadPixelsTreat
29//
30// You can use MBadPixelsTreat::SetUseInterpolation to replaced the
31// bad pixels by the average of its neighbors instead of unmapping
32// them. If you want to include the central pixel use
33// MBadPixelsTreat::SetUseCentralPixel. The bad pixels are taken from
34// an existing MBadPixelsCam.
35//
36// It check if there are enough neighbors to calculate the mean
37// If not, unmap the pixel. The minimum number of good neighbors
38// should be set using SetNumMinNeighbors
39//
40// If you want to interpolate unreliable pixels and unsuitable
41// (broken) pixels use SetHardTreatment().
42//
43//
44// Options:
45// --------
46// SetHardTreatment: Also interpolate unreliable pixels not only unsuitable
47// SetUseInterpolation: Interpolate pixels instead of unmapping them
48// SetUseCentralPixel: also use the pixel itself for interpolation
49// SetProcessPedestalRun: process the pedestals once per run/file
50// SetProcessPedestalEvt: process the pedestal once per event
51// SetProcessTimes: also do some rough interpolation of the arrival time
52//
53//
54// Input Containers:
55// MCerPhotEvt
56// MPedPhotCam
57// MBadPixelsCam
58// [MGeomCam]
59//
60// Output Containers:
61// MCerPhotEvt
62//
63/////////////////////////////////////////////////////////////////////////////
64#include "MBadPixelsTreat.h"
65
66#include <fstream>
67
68#include <TEnv.h>
69
70#include "MArrayD.h" // Used instead of TArrayD because operator[] has no range check
71
72#include "MLog.h"
73#include "MLogManip.h"
74
75#include "MParList.h"
76
77#include "MGeomPix.h"
78#include "MGeomCam.h"
79
80#include "MCerPhotPix.h"
81#include "MCerPhotEvt.h"
82
83#include "MPedPhotPix.h"
84#include "MPedPhotCam.h"
85
86#include "MBadPixelsPix.h"
87#include "MBadPixelsCam.h"
88
89#include "MArrivalTime.h"
90
91ClassImp(MBadPixelsTreat);
92
93using namespace std;
94
95static const TString gsDefName = "MBadPixelsTreat";
96static const TString gsDefTitle = "Task to treat bad pixels (interpolation, unmapping)";
97
98// --------------------------------------------------------------------------
99//
100// Default constructor.
101//
102MBadPixelsTreat::MBadPixelsTreat(const char *name, const char *title)
103 : fFlags(0), fNumMinNeighbors(3), fNamePedPhotCam("MPedPhotCam")
104{
105 fName = name ? name : gsDefName.Data();
106 fTitle = title ? title : gsDefTitle.Data();
107
108 SetUseInterpolation();
109 SetProcessPedestal();
110 SetProcessTimes();
111}
112
113// --------------------------------------------------------------------------
114//
115// Returns the status of a pixel. If kHardTreatment is set a pixel must
116// be unsuitable or uriliable to be treated. If not it is treated only if
117// it is unsuitable
118// (IsBad() checks for any flag)
119//
120Bool_t MBadPixelsTreat::IsPixelBad(Int_t idx) const
121{
122 return TESTBIT(fFlags, kHardTreatment) ? (*fBadPixels)[idx].IsBad():(*fBadPixels)[idx].IsUnsuitable() ;
123}
124
125// --------------------------------------------------------------------------
126//
127// - Try to find or create MBlindPixels in parameter list.
128// - get the MCerPhotEvt from the parlist (abort if missing)
129// - if no pixels are given by the user try to determin the starfield
130// from the monte carlo run header.
131//
132Int_t MBadPixelsTreat::PreProcess (MParList *pList)
133{
134 fBadPixels = (MBadPixelsCam*)pList->FindObject(AddSerialNumber("MBadPixelsCam"));
135 if (!fBadPixels)
136 {
137 *fLog << err << AddSerialNumber("MBadPixelsCam") << " not found... aborting." << endl;
138 return kFALSE;
139 }
140
141 fEvt = (MCerPhotEvt*)pList->FindObject(AddSerialNumber("MCerPhotEvt"));
142 if (!fEvt)
143 {
144 *fLog << err << AddSerialNumber("MCerPhotEvt") << " not found... aborting." << endl;
145 return kFALSE;
146 }
147
148 fGeomCam = 0;
149 if (!IsUseInterpolation())
150 return kTRUE;
151
152 fGeomCam = (MGeomCam*)pList->FindObject(AddSerialNumber("MGeomCam"));
153 if (!fGeomCam)
154 {
155 *fLog << err << AddSerialNumber("MGeomCam") << " not found - can't use interpolation... abort." << endl;
156 *fLog << " Use MBadPixelsTreat::SetUseInterpolation(kFALSE) to switch interpolation" << endl;
157 *fLog << " off and use unmapping instead." << endl;
158 return kFALSE;
159 }
160
161 fPedPhot = 0;
162 if (IsProcessPedestalEvt() || IsProcessPedestalRun())
163 {
164 fPedPhot = (MPedPhotCam*)pList->FindObject(AddSerialNumber(fNamePedPhotCam), "MPedPhotCam");
165 if (!fPedPhot)
166 {
167 *fLog << err << AddSerialNumber("MPedPhotCam") << " not found... aborting." << endl;
168 *fLog << " Use MBadPixelsTreat::SetProcessPedestalRun(kFALSE) and" << endl;
169 *fLog << " MBadPixelsTreat::SetProcessPedestalEvt(kFALSE) to switch" << endl;
170 *fLog << " Pedestal treatment off." << endl;
171 return kFALSE;
172 }
173 }
174
175 fTimes = 0;
176 if (IsProcessTimes())
177 {
178 fTimes = (MArrivalTime*)pList->FindObject(AddSerialNumber("MArrivalTime"));
179 if (!fTimes)
180 {
181 *fLog << err << AddSerialNumber("MArrivalTime") << " not found... aborting." << endl;
182 *fLog << " Use MBadPixelsTreat::SetProcessTimes(kFALSE) to switch time interpolation off." << endl;
183 return kFALSE;
184 }
185 }
186
187 if (IsProcessPedestalEvt())
188 *fLog << inf << "Processing Pedestals once per event..." << endl;
189 if (IsProcessPedestalRun())
190 *fLog << inf << "Processing Pedestals once per run..." << endl;
191 if (IsProcessTimes())
192 *fLog << inf << "Processing Arrival Times once per event..." << endl;
193
194 return kTRUE;
195}
196
197// --------------------------------------------------------------------------
198//
199// Replaces each pixel (signal, signal error, pedestal, pedestal rms)
200// by the average of its surrounding pixels.
201// If TESTBIT(fFlags, kUseCentralPixel) is set the central pixel is also
202// included.
203//
204void MBadPixelsTreat::InterpolateSignal() const
205{
206 const UShort_t entries = fGeomCam->GetNumPixels();
207
208 //
209 // Create arrays (FIXME: Check if its possible to create it only once)
210 //
211 MArrayD nphot(entries);
212 MArrayD perr(entries);
213
214 //
215 // Loop over all pixels
216 //
217 for (UShort_t i=0; i<entries; i++)
218 {
219 MCerPhotPix *pix = fEvt->GetPixById(i);
220
221 //
222 // Check whether pixel with idx i is blind
223 //
224 if (pix && !IsPixelBad(i))
225 continue;
226
227 //
228 // Get a pointer to this pixel. If it is not yet existing
229 // create a new entry for this pixel in MCerPhotEvt
230 //
231 if (!pix)
232 {
233 pix = fEvt->AddPixel(i, 0, 0);
234 (*fBadPixels)[i].SetUnsuitable(MBadPixelsPix::kUnsuitableEvt);
235 }
236
237 //
238 // Get the corresponding geometry and pedestal
239 //
240 const MGeomPix &gpix = (*fGeomCam)[i];
241
242 // Do Not-Use-Central-Pixel
243 const Bool_t nucp = !TESTBIT(fFlags, kUseCentralPixel);
244
245 Int_t num = nucp ? 0 : 1;
246
247 nphot[i] = nucp ? 0 : pix->GetNumPhotons();
248 perr[i] = nucp ? 0 : Pow2(pix->GetErrorPhot());
249
250 //
251 // The values are rescaled to the small pixels area for the right comparison
252 //
253 const Double_t ratio = fGeomCam->GetPixRatio(i);
254
255 nphot[i] *= ratio;
256 perr[i] *= ratio;
257
258 //
259 // Loop over all its neighbors
260 //
261 const Int_t n = gpix.GetNumNeighbors();
262 for (int j=0; j<n; j++)
263 {
264 const UShort_t nidx = gpix.GetNeighbor(j);
265
266 //
267 // Do not use blind neighbors
268 //
269 if (IsPixelBad(nidx))
270 continue;
271
272 //
273 // Check whether the neighbor has a signal stored
274 //
275 const MCerPhotPix *evtpix = fEvt->GetPixById(nidx);
276 if (!evtpix)
277 continue;
278
279 //
280 // Get the geometry for the neighbor
281 //
282 const Double_t nratio = fGeomCam->GetPixRatio(nidx);
283
284 //
285 //The error is calculated as the quadratic sum of the errors
286 //
287 nphot[i] += nratio*evtpix->GetNumPhotons();
288 perr[i] += nratio* Pow2(evtpix->GetErrorPhot());
289
290 num++;
291 }
292
293 // Check if there are enough neighbors to calculate the mean
294 // If not, unmap the pixel. The maximum number of blind neighbors
295 // should be 2
296 if (num<fNumMinNeighbors)
297 {
298 pix->SetPixelUnmapped();
299 continue;
300 }
301
302 //
303 // Now the mean is calculated and the values rescaled back
304 // to the pixel area
305 //
306 nphot[i] /= (num*ratio);
307 perr[i] = TMath::Sqrt(perr[i]/(num*ratio));
308
309 pix->Set(nphot[i], perr[i]);
310 }
311}
312
313// --------------------------------------------------------------------------
314//
315void MBadPixelsTreat::InterpolatePedestals() const
316{
317 const Int_t entries = fPedPhot->GetSize();
318
319 // Create arrays (FIXME: Check if its possible to create it only once)
320 MArrayD ped(entries);
321 MArrayD rms(entries);
322
323 //
324 // Loop over all pixels
325 //
326 for (UShort_t i=0; i<entries; i++)
327 {
328 //
329 // Check whether pixel with idx i is blind
330 //
331 if (!IsPixelBad(i))
332 continue;
333
334 //
335 // Get the corresponding geometry and pedestal
336 //
337 const MGeomPix &gpix = (*fGeomCam)[i];
338 const MPedPhotPix &ppix = (*fPedPhot)[i];
339
340 // Do Not-Use-Central-Pixel
341 const Bool_t nucp = !TESTBIT(fFlags, kUseCentralPixel);
342
343 Int_t num = nucp ? 0 : 1;
344
345 ped[i] = nucp ? 0 : ppix.GetMean();
346 rms[i] = nucp ? 0 : Pow2(ppix.GetRms());
347
348 //
349 // The values are rescaled to the small pixels area for the right comparison
350 //
351 const Double_t ratio = fGeomCam->GetPixRatio(i);
352
353 ped[i] *= ratio;
354 rms[i] *= ratio;
355
356 //
357 // Loop over all its neighbors
358 //
359 const Int_t n = gpix.GetNumNeighbors();
360 for (int j=0; j<n; j++)
361 {
362 const UShort_t nidx = gpix.GetNeighbor(j);
363
364 //
365 // Do not use blind neighbors
366 //
367 if (IsPixelBad(nidx))
368 continue;
369
370 //
371 // Get the geometry for the neighbor
372 //
373 const Double_t nratio = fGeomCam->GetPixRatio(nidx);
374 const MPedPhotPix &nppix = (*fPedPhot)[nidx];
375
376 //
377 //The error is calculated as the quadratic sum of the errors
378 //
379 ped[i] += nratio*nppix.GetMean();
380 rms[i] += nratio*Pow2(nppix.GetRms());
381
382 num++;
383 }
384
385 // Check if there are enough neighbors to calculate the mean
386 // If not, unmap the pixel. The minimum number of good neighbors
387 // should be fNumMinNeighbors
388 if (num < fNumMinNeighbors)
389 {
390 MCerPhotPix *pix =fEvt->GetPixById(i);
391 if (!pix)
392 pix = fEvt->AddPixel(i, 0, 0);
393 pix->SetPixelUnmapped();
394 continue;
395 }
396
397 //
398 // Now the mean is calculated and the values rescaled back
399 // to the pixel area
400 //
401 ped[i] /= (num*ratio);
402 rms[i] = TMath::Sqrt(rms[i]/(num*ratio));
403
404 (*fPedPhot)[i].Set(ped[i], rms[i]);
405 }
406}
407
408// --------------------------------------------------------------------------
409//
410void MBadPixelsTreat::InterpolateTimes() const
411{
412 Int_t n = fTimes->GetSize();
413
414 for (int i=0; i<n; i++)
415 {
416 //
417 // Check whether pixel with idx i is blind
418 //
419 if (!IsPixelBad(i))
420 continue;
421
422 //
423 // Get the corresponding geometry and pedestal
424 //
425 const MGeomPix &gpix = (*fGeomCam)[i];
426
427 const Int_t n0 = gpix.GetNumNeighbors();
428
429 MArrayD time(6);
430 for (int j=0; j<n0; j++)
431 time[j] = (*fTimes)[gpix.GetNeighbor(j)];
432
433 Int_t p0=0;
434 Int_t p1=0;
435
436 Double_t min=FLT_MAX;
437 for (int j=0; j<n0; j++)
438 for (int k=1; k<j+1; k++)
439 {
440 const Double_t diff = TMath::Abs(time[n0-k] - time[n0-k-j]);
441
442 if (diff>=min && diff<250)
443 continue;
444
445 p0 = n0-k;
446 p1 = n0-k-j;
447 min = diff;
448 }
449
450 if (TMath::Abs(time[p0] - time[p1])<250)
451 fTimes->SetTime(i, (time[p0]+time[p1])/2);
452 }
453}
454
455// --------------------------------------------------------------------------
456//
457// Replaces each pixel (signal, signal error, pedestal, pedestal rms)
458// by the average of its surrounding pixels.
459// If TESTBIT(fFlags, kUseCentralPixel) is set the central pixel is also
460// included.
461//
462// NT: Informations about the interpolated pedestals are added.
463// When the option Interpolated is called, the blind pixel with the new
464// values of signal and fluttuation is included in the calculation of
465// the Image Parameters.
466//
467/*
468void MBadPixelsTreat::Interpolate() const
469{
470 const UShort_t entries = fGeomCam->GetNumPixels();
471
472 //
473 // Create arrays
474 //
475 TArrayD nphot(entries);
476 TArrayD perr(entries);
477 TArrayD ped(entries);
478 TArrayD pedrms(entries);
479
480 //
481 // Loop over all pixels
482 //
483 for (UShort_t i=0; i<entries; i++)
484 {
485 MCerPhotPix *pix = fEvt->GetPixById(i);
486
487 //
488 // Check whether pixel with idx i is blind
489 //
490 if (pix && (*fBadPixels)[i].IsOK())
491 continue;
492
493 //
494 // Get a pointer to this pixel. If it is not yet existing
495 // create a new entry for this pixel in MCerPhotEvt
496 //
497 if (!pix)
498 {
499 pix = fEvt->AddPixel(i, 0, 0);
500 (*fBadPixels)[i].SetUnsuitable(MBadPixelsPix::kUnsuitableEvt);
501 }
502
503 //
504 // Get the corresponding geometry and pedestal
505 //
506 const MGeomPix &gpix = (*fGeomCam)[i];
507 const MPedPhotPix &ppix = (*fPedPhot)[i];
508
509 // Do Not-Use-Central-Pixel
510 const Bool_t nucp = !TESTBIT(fFlags, kUseCentralPixel);
511
512 Int_t num = nucp ? 0 : 1;
513
514 nphot[i] = nucp ? 0 : pix->GetNumPhotons();
515 ped[i] = nucp ? 0 : ppix.GetMean();
516 perr[i] = nucp ? 0 : Pow2(pix->GetErrorPhot());
517 pedrms[i] = nucp ? 0 : Pow2(ppix.GetRms());
518
519 //
520 // The values are rescaled to the small pixels area for the right comparison
521 //
522 const Double_t ratio = fGeomCam->GetPixRatio(i);
523
524 if (nucp)
525 {
526 nphot[i] *= ratio;
527 perr[i] *= ratio;
528 ped[i] *= ratio;
529 pedrms[i] *= ratio;
530 }
531
532 //
533 // Loop over all its neighbors
534 //
535 const Int_t n = gpix.GetNumNeighbors();
536 for (int j=0; j<n; j++)
537 {
538 const UShort_t nidx = gpix.GetNeighbor(j);
539
540 //
541 // Do not use blind neighbors
542 //
543 if ((*fBadPixels)[nidx].IsBad())
544 continue;
545
546 //
547 // Check whether the neighbor has a signal stored
548 //
549 const MCerPhotPix *evtpix = fEvt->GetPixById(nidx);
550 if (!evtpix)
551 continue;
552
553 //
554 // Get the geometry for the neighbor
555 //
556 const Double_t nratio = fGeomCam->GetPixRatio(nidx);
557 MPedPhotPix &nppix = (*fPedPhot)[nidx];
558
559 //
560 // The error is calculated as the quadratic sum of the errors
561 //
562 nphot[i] += nratio*evtpix->GetNumPhotons();
563 ped[i] += nratio*nppix.GetMean();
564 perr[i] += nratio*Pow2(evtpix->GetErrorPhot());
565 pedrms[i] += nratio*Pow2(nppix.GetRms());
566
567 num++;
568 }
569
570 if (num<fNumMinNeighbors)
571 {
572 pix->SetPixelUnmapped();
573 nphot[i] = 0;
574 ped[i] = 0;
575 perr[i] = 0;
576 pedrms[i] = 0;
577 continue;
578 }
579
580 //
581 // Now the mean is calculated and the values rescaled back to the pixel area
582 //
583 nphot[i] /= num*ratio;
584 ped[i] /= num*ratio;
585 perr[i] = TMath::Sqrt(perr[i]/(num*ratio));
586 pedrms[i] = TMath::Sqrt(pedrms[i]/(num*ratio));
587
588 }
589
590 //
591 // Now the new pixel values are calculated and can be replaced in
592 // the corresponding containers
593 //
594 for (UShort_t i=0; i<entries; i++)
595 {
596 //
597 // Do not use blind neighbors
598 //
599 if ((*fBadPixels)[i].IsOK())
600 continue;
601
602 //
603 // It must exist, we have created it in the loop before.
604 //
605 fEvt->GetPixById(i)->Set(nphot[i], perr[i]);
606 (*fPedPhot)[i].Set(ped[i], pedrms[i]);
607 }
608}
609*/
610
611// --------------------------------------------------------------------------
612//
613// Removes all blind pixels from the analysis by setting their state
614// to unused.
615//
616void MBadPixelsTreat::Unmap() const
617{
618 const UShort_t entries = fEvt->GetNumPixels();
619
620 //
621 // remove the pixels in fPixelsIdx if they are set to be used,
622 // (set them to 'unused' state)
623 //
624 for (UShort_t i=0; i<entries; i++)
625 {
626 MCerPhotPix &pix = (*fEvt)[i];
627
628 if (IsPixelBad(pix.GetPixId()))
629 pix.SetPixelUnmapped();
630 }
631}
632
633// --------------------------------------------------------------------------
634//
635// Interpolate Pedestals if kProcessPedestal not set
636//
637Bool_t MBadPixelsTreat::ReInit(MParList *pList)
638{
639 if (IsUseInterpolation() && IsProcessPedestalRun())
640 InterpolatePedestals();
641 return kTRUE;
642}
643
644// --------------------------------------------------------------------------
645//
646// Treat the blind pixels
647//
648Int_t MBadPixelsTreat::Process()
649{
650 if (IsUseInterpolation())
651 {
652 InterpolateSignal();
653 if (IsProcessPedestalEvt())
654 InterpolatePedestals();
655 if (IsProcessTimes())
656 InterpolateTimes();
657 }
658 else
659 Unmap();
660
661 return kTRUE;
662}
663
664void MBadPixelsTreat::StreamPrimitive(ofstream &out) const
665{
666 out << " MBadPixelsTreat " << GetUniqueName();
667 if (fName!=gsDefName || fTitle!=gsDefTitle)
668 {
669 out << "(\"" << fName << "\"";
670 if (fTitle!=gsDefTitle)
671 out << ", \"" << fTitle << "\"";
672 out <<")";
673 }
674 out << ";" << endl;
675
676 if (IsUseInterpolation())
677 out << " " << GetUniqueName() << ".SetUseInterpolation();" << endl;
678 if (IsUseCentralPixel())
679 out << " " << GetUniqueName() << ".SetUseCentralPixel();" << endl;
680 if (IsProcessPedestalRun())
681 out << " " << GetUniqueName() << ".SetProcessPedestalRun();" << endl;
682 if (IsProcessPedestalEvt())
683 out << " " << GetUniqueName() << ".SetProcessPedestalEvt();" << endl;
684 if (IsProcessTimes())
685 out << " " << GetUniqueName() << ".SetProcessTimes();" << endl;
686 if (IsHardTreatment())
687 out << " " << GetUniqueName() << ".SetHardTreatment();" << endl;
688 if (fNumMinNeighbors!=3)
689 out << " " << GetUniqueName() << ".SetNumMinNeighbors(" << (int)fNumMinNeighbors << ");" << endl;
690}
691
692// --------------------------------------------------------------------------
693//
694// Read the setup from a TEnv, eg:
695// MBadPixelsTreat.UseInterpolation: no
696// MBadPixelsTreat.UseCentralPixel: no
697// MBadPixelsTreat.HardTreatment: no
698// MBadPixelsTreat.ProcessPedestalRun: no
699// MBadPixelsTreat.ProcessPedestalEvt: no
700// MBadPixelsTreat.NumMinNeighbors: 3
701//
702Int_t MBadPixelsTreat::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
703{
704 Bool_t rc = kFALSE;
705 if (IsEnvDefined(env, prefix, "UseInterpolation", print))
706 {
707 rc = kTRUE;
708 SetUseInterpolation(GetEnvValue(env, prefix, "UseInterpolation", IsUseInterpolation()));
709 }
710 if (IsEnvDefined(env, prefix, "UseCentralPixel", print))
711 {
712 rc = kTRUE;
713 SetUseCentralPixel(GetEnvValue(env, prefix, "UseCentralPixel", IsUseCentralPixel()));
714 }
715 if (IsEnvDefined(env, prefix, "HardTreatment", print))
716 {
717 rc = kTRUE;
718 SetHardTreatment(GetEnvValue(env, prefix, "HardTreatment", IsHardTreatment()));
719 }
720 if (IsEnvDefined(env, prefix, "ProcessPedestalRun", print))
721 {
722 rc = kTRUE;
723 SetProcessPedestalRun(GetEnvValue(env, prefix, "ProcessPedestalRun", IsProcessPedestalRun()));
724 }
725 if (IsEnvDefined(env, prefix, "ProcessPedestalEvt", print))
726 {
727 rc = kTRUE;
728 SetProcessPedestalEvt(GetEnvValue(env, prefix, "ProcessPedestalEvt", IsProcessPedestalEvt()));
729 }
730 if (IsEnvDefined(env, prefix, "ProcessTimes", print))
731 {
732 rc = kTRUE;
733 SetProcessTimes(GetEnvValue(env, prefix, "ProcessTimes", IsProcessTimes()));
734 }
735 if (IsEnvDefined(env, prefix, "NumMinNeighbors", print))
736 {
737 rc = kTRUE;
738 SetNumMinNeighbors(GetEnvValue(env, prefix, "NumMinNeighbors", fNumMinNeighbors));
739 }
740 return rc;
741}
Note: See TracBrowser for help on using the repository browser.