All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
icarus_tool::Response Class Reference
Inheritance diagram for icarus_tool::Response:
icarus_tool::IResponse

Public Member Functions

 Response (const fhicl::ParameterSet &pset)
 
 ~Response ()
 
void configure (const fhicl::ParameterSet &pset) override
 Setup routines. More...
 
void setResponse (double sampling_rate, double weight) override
 
void outputHistograms (double sampling_rate, art::TFileDirectory &) const override
 
size_t getPlane () const override
 Return the plane these functions represent. More...
 
const IFieldResponsegetFieldResponse () const override
 Recover the individual response elements. More...
 
const IElectronicsResponsegetElectronicsResponse () const override
 
const IFiltergetFilter () const override
 
size_t getNumberTimeSamples () const override
 here recover the combined response elements More...
 
const icarusutil::TimeVecgetResponse () const override
 
const icarusutil::FrequencyVecgetConvKernel () const override
 
const icarusutil::FrequencyVecgetDeconvKernel () const override
 
double getTOffset () const override
 

Private Types

using IFieldResponsePtr = std::unique_ptr< icarus_tool::IFieldResponse >
 
using IElectronicsResponsePtr = std::unique_ptr< icarus_tool::IElectronicsResponse >
 
using IFilterPtr = std::unique_ptr< icarus_tool::IFilter >
 

Private Member Functions

void calculateResponse (double sampling_rate, double weight)
 
std::string numberToString (int number)
 
- Private Member Functions inherited from icarus_tool::IResponse
virtual ~IResponse () noexcept=default
 

Private Attributes

bool fResponseHasBeenSet
 
size_t fThisPlane
 
double f3DCorrection
 
double fTimeScaleFactor
 
IFieldResponsePtr fFieldResponse
 
IElectronicsResponsePtr fElectronicsResponse
 
IFilterPtr fFilter
 
size_t fNumberTimeSamples
 
icarusutil::TimeVec fResponse
 
icarusutil::FrequencyVec fConvolutionKernel
 
icarusutil::FrequencyVec fDeconvolutionKernel
 
bool fUseEmpiricalOffsets
 Use emperical offsets divined from data. More...
 
double fT0Offset
 The overall T0 offset for the response function. More...
 
std::unique_ptr
< icarus_signal_processing::ICARUSFFT
< double > > 
fFFT
 Object to handle thread safe FFT. More...
 

Detailed Description

Definition at line 34 of file Response_tool.cc.

Member Typedef Documentation

Definition at line 74 of file Response_tool.cc.

Definition at line 73 of file Response_tool.cc.

using icarus_tool::Response::IFilterPtr = std::unique_ptr<icarus_tool::IFilter>
private

Definition at line 75 of file Response_tool.cc.

Constructor & Destructor Documentation

icarus_tool::Response::Response ( const fhicl::ParameterSet &  pset)
explicit

Definition at line 96 of file Response_tool.cc.

97 {
98  configure(pset);
99 }
void configure(const fhicl::ParameterSet &pset) override
Setup routines.
icarus_tool::Response::~Response ( )
inline

Definition at line 39 of file Response_tool.cc.

39 {}

Member Function Documentation

void icarus_tool::Response::calculateResponse ( double  sampling_rate,
double  weight 
)
private

Definition at line 183 of file Response_tool.cc.

185 {
186  // First of all set the field response
187  fFieldResponse->setResponse(weight, f3DCorrection, fTimeScaleFactor);
188 
189  // What kind of response? (0= first induction, 1= middle induction, 2= collection)
190  size_t responseType = fFieldResponse->getResponseType();
191 
192  // handle the electronics response for this plane
193  fElectronicsResponse->setResponse(fFieldResponse->getResponseVec().size(), fFieldResponse->getBinWidth());
194 
195  // Next we perform the convolution of the field and electronics responses and then invert to get the
196  // interim response function which will be set up in the time binning/range of the field response
197  const icarusutil::FrequencyVec& fieldResponseFFTVec = fFieldResponse->getResponseFFTVec();
198  const icarusutil::FrequencyVec& electronicsResponseFFTVec = fElectronicsResponse->getResponseFFTVec();
199 
200  icarusutil::FrequencyVec curResponseFFTVec(fieldResponseFFTVec.size());
201 
202  std::transform(fieldResponseFFTVec.begin(), fieldResponseFFTVec.begin() + fieldResponseFFTVec.size()/2, electronicsResponseFFTVec.begin(), curResponseFFTVec.begin(), std::multiplies<icarusutil::ComplexVal>());
203 
204  // And now we recover the current response vector which is the convolution of the two above
205  // (and still in the units of the original field response)
206  icarusutil::TimeVec curResponseVec(fieldResponseFFTVec.size());
207 
208  // Note that we need a local version of the FFT because our time samples currently don't match what we will have
209  icarus_signal_processing::ICARUSFFT<double> locFFT(curResponseVec.size());
210 
211  locFFT.inverseFFT(curResponseFFTVec, curResponseVec);
212 
213  // Now set to the task of determing the actual sampling response
214  // We have to remember that the bin size for determining the field response probably
215  // does not match that for the detector readout so we'll need to "convert"
216  // from one to the other.
217  fResponse.resize(fNumberTimeSamples, 0.);
218 
219  // Recover the combined response from above
220 // const std::vector<double>& curResponseVec = fSignalShapingICARUS.Response_save();
221 
222  double respIntegral = std::accumulate(curResponseVec.begin(),curResponseVec.end(),0.);
223 
224  mf::LogInfo("Response_tool") << "***** Response for plane: " << fThisPlane << " ******" << "\n"
225  << " initial response integral: " << respIntegral << std::endl;
226 
227  // Need two factors: 1) the detector sampling rate and 2) the response sampling rate
228  double samplingRate = sampling_rate; // This is input in ns/tick
229  double responseRate = fFieldResponse->getBinWidth(); // This is returned in ns
230  double rateRatio = samplingRate / responseRate; // This gives the ratio of time bins for full readout to response bins
231 
232  // The idea is to step through each bin of the sampling response vector and then to
233  // look up the corresponding bins in the current response vector. Since the two sample
234  // rates are not the same there will be some "stretching" between the two. In addition,
235  // we want to continue to allow for the possibility for further sample stretching
236  double binScaleFactor = rateRatio * f3DCorrection * fTimeScaleFactor;
237 
238  // ok, do the loop
239  for(size_t sampleIdx = 0; sampleIdx < fNumberTimeSamples; sampleIdx++)
240  {
241  // calculate the index for the response
242  size_t responseLowIdx = std::floor(sampleIdx * binScaleFactor);
243 
244  if (responseLowIdx < curResponseVec.size())
245  {
246  // Calculate the index for the next bin
247  size_t responseHiIdx = std::floor((sampleIdx + 1) * binScaleFactor);
248 
249  // This can't happen? But protect against zero divides...
250  if (responseHiIdx == responseLowIdx) responseHiIdx += 1;
251 
252  if (responseHiIdx >= curResponseVec.size()) break;
253 
254  icarusutil::TimeVec::const_iterator curResponseItr = curResponseVec.begin();
255 
256  std::advance(curResponseItr,responseLowIdx);
257 
258  int nBins = responseHiIdx - responseLowIdx;
259 
260  // Obtain the average of these bins
261  double aveResponse = std::accumulate(curResponseItr,curResponseItr+nBins,0.)/double(nBins);
262 
263  // Now interpolate between the two bins to get the sampling response for this bin
264 // double responseSlope = (curResponseVec.at(responseHiIdx) - curResponseVec.at(responseLowIdx)) / (responseHiIdx - responseLowIdx);
265 // double response = curResponseVec.at(responseLowIdx) + 0.5 * responseSlope * (responseHiIdx - responseLowIdx);
266 
267  fResponse[sampleIdx] = aveResponse;
268  }
269  }
270 
271  // We need to scale by the binScaleFactor to preserve normalization
272  std::transform(fResponse.begin(),fResponse.end(),fResponse.begin(),std::bind(std::multiplies<double>(),std::placeholders::_1,binScaleFactor));
273 
274  respIntegral = std::accumulate(fResponse.begin(),fResponse.end(),0.);
275 
276  // Now compute the T0 offset for the response function
277  std::pair<icarusutil::TimeVec::iterator,icarusutil::TimeVec::iterator> minMaxPair = std::minmax_element(fResponse.begin(),fResponse.end());
278 
279  // Calculation of the T0 offset depends on the signal type
280  int timeBin = std::distance(fResponse.begin(),minMaxPair.first);
281 
282  if (responseType == 2) timeBin = std::distance(fResponse.begin(),minMaxPair.second);
283  else
284  {
285  std::cout << "*** plane: " << fThisPlane << ", first idx/val: " << std::distance(fResponse.begin(),minMaxPair.first) << "/" << *minMaxPair.first << ", second idx/val: " << std::distance(fResponse.begin(),minMaxPair.second) << "/" << *minMaxPair.second << std::endl;
286  double weightSum = abs(*minMaxPair.first) + abs(*minMaxPair.second);
287  double sum = std::distance(fResponse.begin(),minMaxPair.first) * abs(*minMaxPair.first) + std::distance(fResponse.begin(),minMaxPair.second) * abs(*minMaxPair.second);
288 
289  timeBin = std::round(sum/weightSum);
290  }
291 
292  std::cout << "*** Response tool is setting timeBin = " << timeBin << std::endl;
293 
294  if (fUseEmpiricalOffsets && fThisPlane == 0) timeBin = 83.;
295  if (fUseEmpiricalOffsets && fThisPlane == 1) timeBin = 83.;
296 
297 // // Do a backwards search to find the first positive bin
298 // while(1)
299 // {
300 // // Did we go too far?
301 // if (timeBin < 0)
302 // throw cet::exception("Response::configure") << "Cannot find zero-point crossover for induction response! ResponseType: " << responseType << ", plane: " << fThisPlane << std::endl;
303 //
304 // double content = fResponse[timeBin];
305 //
306 // if (content >= 0.) break;
307 //
308 // timeBin--;
309 // }
310 //
311 //
312  fT0Offset = -timeBin; // Note that this value being returned is in tick units now
313 
314  std::cout << "** Response tool for plane: " << fThisPlane << ", T0: " << fT0Offset << std::endl;
315 
316  mf::LogInfo("Response_tool") << " final response integral: " << respIntegral << ", T0Offset: " << fT0Offset << std::endl;
317 
318  return;
319 }
IElectronicsResponsePtr fElectronicsResponse
static constexpr Sample_t transform(Sample_t sample)
IFieldResponsePtr fFieldResponse
double fT0Offset
The overall T0 offset for the response function.
std::vector< ComplexVal > FrequencyVec
T abs(T value)
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
std::vector< SigProcPrecision > TimeVec
bool fUseEmpiricalOffsets
Use emperical offsets divined from data.
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
BEGIN_PROLOG could also be cout
icarusutil::TimeVec fResponse
void icarus_tool::Response::configure ( const fhicl::ParameterSet &  pset)
overridevirtual

Setup routines.

Parameters
outputthe object containting the art output
clusHitPairVectorList of 3D hits to output as "extreme" space points

Implements icarus_tool::IResponse.

Definition at line 101 of file Response_tool.cc.

102 {
103  // Start by recovering the parameters
104  fThisPlane = pset.get<size_t>("Plane");
105  f3DCorrection = pset.get<size_t>("Correction3D");
106  fTimeScaleFactor = pset.get<size_t>("TimeScaleFactor");
107  fUseEmpiricalOffsets = pset.get<bool >("UseEmpiricalOffsets");
108 
109  fResponseHasBeenSet = false;
110 
111  // Build out the underlying tools we'll be using
112  fFieldResponse = art::make_tool<icarus_tool::IFieldResponse>(pset.get<fhicl::ParameterSet>("FieldResponse"));
113  fElectronicsResponse = art::make_tool<icarus_tool::IElectronicsResponse>(pset.get<fhicl::ParameterSet>("ElectronicsResponse"));
114  fFilter = art::make_tool<icarus_tool::IFilter>(pset.get<fhicl::ParameterSet>("Filter"));
115 
116  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob();
117  fNumberTimeSamples = detProp.NumberTimeSamples();
118 
119  // Now set up our plans for doing the convolution
120  fFFT = std::make_unique<icarus_signal_processing::ICARUSFFT<double>>(fNumberTimeSamples);
121 
122  return;
123 }
IElectronicsResponsePtr fElectronicsResponse
IFieldResponsePtr fFieldResponse
std::unique_ptr< icarus_signal_processing::ICARUSFFT< double > > fFFT
Object to handle thread safe FFT.
bool fUseEmpiricalOffsets
Use emperical offsets divined from data.
auto const detProp
const icarusutil::FrequencyVec& icarus_tool::Response::getConvKernel ( ) const
inlineoverridevirtual

Implements icarus_tool::IResponse.

Definition at line 53 of file Response_tool.cc.

53 {return fConvolutionKernel;}
icarusutil::FrequencyVec fConvolutionKernel
const icarusutil::FrequencyVec& icarus_tool::Response::getDeconvKernel ( ) const
inlineoverridevirtual

Implements icarus_tool::IResponse.

Definition at line 54 of file Response_tool.cc.

54 {return fDeconvolutionKernel;}
icarusutil::FrequencyVec fDeconvolutionKernel
const IElectronicsResponse* icarus_tool::Response::getElectronicsResponse ( ) const
inlineoverridevirtual

Implements icarus_tool::IResponse.

Definition at line 48 of file Response_tool.cc.

48 {return fElectronicsResponse.get();}
IElectronicsResponsePtr fElectronicsResponse
const IFieldResponse* icarus_tool::Response::getFieldResponse ( ) const
inlineoverridevirtual

Recover the individual response elements.

Implements icarus_tool::IResponse.

Definition at line 47 of file Response_tool.cc.

47 {return fFieldResponse.get();}
IFieldResponsePtr fFieldResponse
const IFilter* icarus_tool::Response::getFilter ( ) const
inlineoverridevirtual

Implements icarus_tool::IResponse.

Definition at line 49 of file Response_tool.cc.

49 {return fFilter.get();}
size_t icarus_tool::Response::getNumberTimeSamples ( ) const
inlineoverridevirtual

here recover the combined response elements

Parameters
outputthe object containting the art output
clusHitPairVectorList of 3D hits to output as "extreme" space points

Implements icarus_tool::IResponse.

Definition at line 51 of file Response_tool.cc.

51 {return fNumberTimeSamples;}
size_t icarus_tool::Response::getPlane ( ) const
inlineoverridevirtual

Return the plane these functions represent.

Implements icarus_tool::IResponse.

Definition at line 45 of file Response_tool.cc.

45 {return fThisPlane;}
const icarusutil::TimeVec& icarus_tool::Response::getResponse ( ) const
inlineoverridevirtual

Implements icarus_tool::IResponse.

Definition at line 52 of file Response_tool.cc.

52 {return fResponse;}
icarusutil::TimeVec fResponse
double icarus_tool::Response::getTOffset ( ) const
inlineoverridevirtual

Implements icarus_tool::IResponse.

Definition at line 55 of file Response_tool.cc.

55 {return fT0Offset;};
double fT0Offset
The overall T0 offset for the response function.
std::string icarus_tool::Response::numberToString ( int  number)
private

Definition at line 392 of file Response_tool.cc.

393 {
394  std::ostringstream string;
395 
396  string << std::setfill('0') << std::setw(2) << number;
397 
398  return string.str();
399 }
void icarus_tool::Response::outputHistograms ( double  sampling_rate,
art::TFileDirectory &  histDir 
) const
overridevirtual

Implements icarus_tool::IResponse.

Definition at line 321 of file Response_tool.cc.

323 {
324  // Create a subfolder in which to place the "response" histograms
325  std::string thisResponse = "ResponsesPlane_" + std::to_string(fThisPlane);
326 
327  art::TFileDirectory dir = histDir.mkdir(thisResponse.c_str());
328 
329  // Do the field response histograms
330  fFieldResponse->outputHistograms(dir);
331  fElectronicsResponse->outputHistograms(dir);
332  fFilter->outputHistograms(dir);
333 
334  // Now make hists for the full response
335  std::string dirName = "Response_" + std::to_string(fThisPlane);
336 
337  art::TFileDirectory responesDir = dir.mkdir(dirName.c_str());
338  const icarusutil::TimeVec& responseVec = fResponse;
339  double numBins = responseVec.size();
340  double samplingRate = sampling_rate; // Sampling time in us
341  double maxFreq = 1. / samplingRate; // Max frequency in MHz
342  double minFreq = maxFreq / numBins;
343  std::string histName = "Response_Plane_" + std::to_string(fThisPlane);
344  TProfile* hist = dir.make<TProfile>(histName.c_str(), "Response;Time(us)", numBins, 0., numBins * sampling_rate * 1.e-3);
345 
346  for(int bin = 0; bin < numBins; bin++)
347  {
348  hist->Fill((double(bin) + 0.5) * sampling_rate * 1.e-3, responseVec.at(bin), 1.);
349  }
350 
351  icarusutil::TimeVec powerVec;
352 
353  fFFT->getFFTPower(responseVec, powerVec);
354 
355  std::string freqName = "Response_FFTPlane_" + std::to_string(fThisPlane);
356  TProfile* freqHist = dir.make<TProfile>(freqName.c_str(), "Response;Frequency(kHz)", numBins/2, minFreq, 0.5*maxFreq);
357 
358  for(size_t idx = 0; idx < numBins/2; idx++)
359  {
360  double freq = minFreq * (idx + 0.5);
361 
362  freqHist->Fill(freq, powerVec.at(idx), 1.);
363  }
364 
365  const icarusutil::FrequencyVec& convKernel = fConvolutionKernel;
366 
367  std::string convKernelName = "ConvKernel_" + std::to_string(fThisPlane);
368  TProfile* fullResponseHist = dir.make<TProfile>(convKernelName.c_str(), "Convolution Kernel;Frequency(kHz)", numBins/2, minFreq, 0.5*maxFreq);
369 
370  for(size_t idx = 0; idx < numBins/2; idx++)
371  {
372  double freq = minFreq * (idx + 0.5);
373 
374  fullResponseHist->Fill(freq, std::abs(convKernel[idx]), 1.);
375  }
376 
377  const icarusutil::FrequencyVec& deconKernel = fDeconvolutionKernel;
378 
379  std::string deconName = "DeconKernel_" + std::to_string(fThisPlane);
380  TProfile* deconHist = dir.make<TProfile>(deconName.c_str(), "Deconvolution Kernel;Frequency(kHz)", numBins/2, minFreq, 0.5*maxFreq);
381 
382  for(size_t idx = 0; idx < numBins/2; idx++)
383  {
384  double freq = minFreq * (idx + 0.5);
385 
386  deconHist->Fill(freq, std::abs(deconKernel[idx]), 1.);
387  }
388 
389  return;
390 }
IElectronicsResponsePtr fElectronicsResponse
IFieldResponsePtr fFieldResponse
std::vector< ComplexVal > FrequencyVec
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
T abs(T value)
std::unique_ptr< icarus_signal_processing::ICARUSFFT< double > > fFFT
Object to handle thread safe FFT.
std::vector< SigProcPrecision > TimeVec
icarusutil::FrequencyVec fConvolutionKernel
tuple dir
Definition: dropbox.py:28
std::string to_string(WindowPattern const &pattern)
do i e
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
icarusutil::FrequencyVec fDeconvolutionKernel
icarusutil::TimeVec fResponse
void icarus_tool::Response::setResponse ( double  sampling_rate,
double  weight 
)
overridevirtual

Implements icarus_tool::IResponse.

Definition at line 125 of file Response_tool.cc.

126 {
127  // If we have already done the setup then can return
128  if (fResponseHasBeenSet) return;
129 
130  // Calculate the combined field and electronics shaping response
132 
133  // Now we compute the convolution kernel which is a straigtforward operation
134  fFFT->forwardFFT(fResponse, fConvolutionKernel);
135 
136  // Set up the filter for use in the deconvolution
138 
139  // Now compute the deconvolution kernel
140  fDeconvolutionKernel = fFilter->getResponseVec();
141 
142  for(size_t idx = 0; idx < fNumberTimeSamples; idx++)
143  {
144  if (std::abs(fConvolutionKernel[idx]) < 0.0001) fDeconvolutionKernel[idx] = 0.;
145  else fDeconvolutionKernel[idx] /= fConvolutionKernel[idx];
146  }
147 
148  // The following can be uncommented to do some consistency checks if desired
149 // // Do some consistency/cross checks here
150 // // Check area of convolution function
151 // const std::vector<TComplex>& convKernel = fSignalShapingICARUS.ConvKernel();
152 //
153 // double normFactor = std::accumulate(convKernel.begin(),convKernel.end(),0.,[](const auto& val, double sum){return sum + std::abs(val);});
154 //
155 // mf::LogInfo("Response_tool") << "Response for plane: " << fThisPlane << ", convKernel integral: " << normFactor << std::endl;
156 //
157 // const std::vector<TComplex>& deconvKernel = fSignalShapingICARUS.DeconvKernel();
158 // std::vector<TComplex> combKernel(deconvKernel.size());
159 //
160 // std::transform(convKernel.begin(),convKernel.end(),deconvKernel.begin(),combKernel.begin(),std::multiplies<TComplex>());
161 //
162 // const std::vector<TComplex>& filterKernel = fSignalShapingICARUS.Filter();
163 //
164 // int diffCount(0);
165 // double maxRhoDiff(0.);
166 //
167 // for(size_t idx = 0; idx < filterKernel.size(); idx++)
168 // {
169 // double rhoDiff = filterKernel[idx].Rho() - combKernel[idx].Rho();
170 //
171 // if (std::abs(rhoDiff) > 0.001) diffCount++;
172 //
173 // if (std::abs(rhoDiff) > std::abs(maxRhoDiff)) maxRhoDiff = rhoDiff;
174 // }
175 //
176 // mf::LogInfo("Response_tool") << "Checking recovery of the filter, # differences: " << diffCount << ", max diff seen: " << maxRhoDiff << std::endl;
177 
178  fResponseHasBeenSet = true;
179 
180  return;
181 }
void calculateResponse(double sampling_rate, double weight)
T abs(T value)
std::unique_ptr< icarus_signal_processing::ICARUSFFT< double > > fFFT
Object to handle thread safe FFT.
icarusutil::FrequencyVec fConvolutionKernel
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
icarusutil::FrequencyVec fDeconvolutionKernel
icarusutil::TimeVec fResponse

Member Data Documentation

double icarus_tool::Response::f3DCorrection
private

Definition at line 70 of file Response_tool.cc.

icarusutil::FrequencyVec icarus_tool::Response::fConvolutionKernel
private

Definition at line 85 of file Response_tool.cc.

icarusutil::FrequencyVec icarus_tool::Response::fDeconvolutionKernel
private

Definition at line 86 of file Response_tool.cc.

IElectronicsResponsePtr icarus_tool::Response::fElectronicsResponse
private

Definition at line 79 of file Response_tool.cc.

std::unique_ptr<icarus_signal_processing::ICARUSFFT<double> > icarus_tool::Response::fFFT
private

Object to handle thread safe FFT.

Definition at line 91 of file Response_tool.cc.

IFieldResponsePtr icarus_tool::Response::fFieldResponse
private

Definition at line 78 of file Response_tool.cc.

IFilterPtr icarus_tool::Response::fFilter
private

Definition at line 80 of file Response_tool.cc.

size_t icarus_tool::Response::fNumberTimeSamples
private

Definition at line 83 of file Response_tool.cc.

icarusutil::TimeVec icarus_tool::Response::fResponse
private

Definition at line 84 of file Response_tool.cc.

bool icarus_tool::Response::fResponseHasBeenSet
private

Definition at line 66 of file Response_tool.cc.

double icarus_tool::Response::fT0Offset
private

The overall T0 offset for the response function.

Definition at line 89 of file Response_tool.cc.

size_t icarus_tool::Response::fThisPlane
private

Definition at line 69 of file Response_tool.cc.

double icarus_tool::Response::fTimeScaleFactor
private

Definition at line 71 of file Response_tool.cc.

bool icarus_tool::Response::fUseEmpiricalOffsets
private

Use emperical offsets divined from data.

Definition at line 88 of file Response_tool.cc.


The documentation for this class was generated from the following file: