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 IFieldResponse * getFieldResponse () const override
 Recover the individual response elements. More...
 
const IElectronicsResponse * getElectronicsResponse () const override
 
const IFilter * getFilter () const override
 
size_t getNumberTimeSamples () const override
 here recover the combined response elements More...
 
const icarusutil::TimeVec & getResponse () const override
 
const icarusutil::FrequencyVec & getConvKernel () const override
 
const icarusutil::FrequencyVec & getDeconvKernel () 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: