.. _modules: Radcube Modules, Services, and Segments ======================================= A number of modules are included in the :ref:`radcube` project. A good portion of these are involved in the reading in of simulated air showers (see :ref:`secCoreasSimulations`) and the convolution of the simulated electric fields with the detector response, ultimately producing data that is in a format that is identical to that which would come from the Pole. In this way, the code can treat simulated and real data symmetrically when performing high level analyses. The remaining modules are involved in the pre-processing of data, removing the detector response and performing estimates of the shower properties. Note that the reconstruction itself is not done in this project, rather, it is contained solely in the :ref:`rockbottom` project. -------- Modules -------- .. _AddElectronicNoise: ^^^^^^^^^^^^^^^^^^ AddElectronicNoise ^^^^^^^^^^^^^^^^^^ This module adds noise to a trace which is consistent with what is measured in the DAQ hardware. The baseline inclusion of noise is that of the TAXI system. The noise profile of other DAQ configurations can also be chosen using input flags. Alternatively, noise with a flat spectrum can be added by setting the ``FlatNoiseLevel`` parameter to the desired dBm/Hz. The noise for the various settings is taken from an average frequency spectrum. Thus if the injected noise spectrum is plotted, it should always look the same. However, the phase of the noise is randomly assigned. ``AddElectronicNoise`` includes the following parameters: - **ApplyInDAQ**: If ``True``, all sources of noise will be added in the Q-frame, otherwise the P-frame - **FlatNoiseLevel**: If set, flat noise will be added wtih the input value (in dBm/Hz) - **KeepNoiseOnly**: If ``True``, the pure noise waveform will be added to the frame - **InputName**: Name of the ``I3AntennaDataMap`` in the frame to which noise will be added - **OutputName**: Name that the resultant ``I3AntennaDataMap`` that will be placed in the frame - **RandomServiceName**: Name of the RandomService in the context used to generate random numbers (for the phases) .. _AddPhaseDelay: ^^^^^^^^^^^^^^ AddPhaseDelay ^^^^^^^^^^^^^^ One of the properties of working in the Fourier domain is that the signals are guaranteed to be continuous from the last bin and wrapping back around to the first. Thus, it is possible to "roll" the signals within the bins and this module does just that. Given a delay time, it will roll the signal by that amount of time via the addition of a phase gradient :math:`\exp{(i\,f\,\Delta t)}`. ``AddPhaseDelay`` includes the following parameters: - **DelayTime**: The amount of time to delay the signals. - **ApplyInDAQ**: If ``True``, all sources of noise will be added in the Q-frame, otherwise the P-frame - **InputName**: Name of the ``I3AntennaDataMap`` or the ``EFieldTimeSeriesMap`` in the frame to which noise will be added - **OutputName**: Name that the resultant ``I3AntennaDataMap`` or ``EFieldTimeSeriesMap`` that will be placed in the frame .. _BandpassFilter: ^^^^^^^^^^^^^^^ BandpassFilter ^^^^^^^^^^^^^^^ The ``BandpassFilter`` module is well named. It simply applies a filter to the selected set of waveforms. ``BandpassFilter`` includes the following parameters: - **ApplyInDAQ**: If ``True``, the filtering will be performed in the Q-frame, otherwise the P-frame - **BoxTimeDelay**: This is a delay parameter that can be added to the box-filter. It directly shifts the entire signal in the time domain by the selected about (in ``I3Units``). Note that the trace is cyclic, so too negative of a number will put the trace at the end, giving potentially strange results. - **ButterworthOrder**: This is the order of the Butterworth filter, describing the rate of attenuation outside of the bandpass region - **FilterLimits**: List containing the (low, high) limits of the filter to apply. Typically, the limits for a bandpass filter are defined as where the attenuation reaches -3dB. - **FilterType**: Type of filter to apply - **InputName**: Name of the ``I3AntennaDataMap`` or ``EFieldTimeSeriesMap`` in the frame which will be filtered - **OutputName**: Name that the resultant ``I3AntennaDataMap`` or ``EFieldTimeSeriesMap`` that will be placed in the frame .. _BringTheNoise: ^^^^^^^^^^^^^^ BringTheNoise ^^^^^^^^^^^^^^ This module has the ability to add thermal [#thermalnoisenote]_ and/or Cane noise. The Cane noise is a model that describes the average emission of electromagnetic radiation, as a function of frequency, from extra-terrestrial sources. For more information on the Cane model, see :ref:`cane_noise_brightness`. The amplitude of the selected noise sources is calculated then a random phase is added. These complex Fourier amplitudes are added to the requested trace. Additionally, an ``I3AntennaDataMap`` consisting of only the noise is also added to the frame for diagnostic purposes called ``GeneratedNoiseMap``. Note that this noise is convolved with the antenna response (thus this module must be linked with the ``I3AntennaResponse``), but it is `not` convolved with the electronics. ``BringTheNoise`` includes the following parameters: - **AntennaResponseName**: (Required) Name of the ``I3AntennaResponse`` service in the frame - **InputName**: Name of the ``I3AntennaDataMap`` in the frame to add noise to - **NoiseMultiplier**: Multiply the noise spectrum amplitudes by this amount, (1 effectively does nothing) - **OutputName**: Name that the resultant ``I3AntennaDataMap`` will be placed in the frame - **RandomServiceName**: The name of the I3RandomService in the tray to use for random number generation. - **ThermalNoiseTemp**: Temperature of the thermal noise to be added. Note: This must be passed in ``I3Units`` - **UseThermalNoise**: If ``True``, thermal noise will be included - **UseCaneNoise**: If ``True``, noise based on the Cane Model (see :ref:`cane_noise_brightness`) will be included - **InsertNoiseOnly**: If ``True``, keep a copy of the pure noise in the frame .. _ChannelInjector: ^^^^^^^^^^^^^^^^ ChannelInjector ^^^^^^^^^^^^^^^^ This module convolves the antenna response with the simulated electric field. This is done via the ``I3AntennaResponse`` service. The voltage in the antenna is calculated using the shower's trajectory as an approximation for the Poynting vector of the radio emission of cosmic rays. .. note:: The Poynting vector of the radio emission is approximately one degree misaligned with the shower axis and this algorithm is thus an approximation. The electric field, :math:`\vec E(f)` is dotted with the antenna's vector effective length :math:`\vec{ \mathcal{L}}(f, \theta, \phi)`. The math describing this process is given in :ref:`VoltageInAnAntenna`. ``ChannelInjector`` includes the following parameters: - **AntennaResponseName**: Name of the ``I3AntennaResponse`` service in the frame - **InputName**: Name of the ``EFieldTimeSeriesMapConstPtr`` in the frame to be transformed into a voltage. - **OutputName**: Name that the resultant ``I3AntennaDataMap`` will be placed in the frame. .. _CoreasReader: ^^^^^^^^^^^^ CoreasReader ^^^^^^^^^^^^ This module's job is to read in the CoREAS showers (see :ref:`secCoreasSimulations`) and put all of the relevant information in the frame. The complexity of this module comes from that fact that it has to able to run on an empty tray. Typically, modules have a constructor, a configuration, and specific functions that are called when the tray gets to a specific type of frame i.e. ``DAQ()`` is called for Q frames. Since we want the abililty for this module to run with an empty tray , it needs the ability to bootstrap all of the frames. Thus, ``CoreasReader`` makes use of a number of non-standard module functions, such as ``ShouldDoProcess()``. However, this reader is also compatible with having other modules do the "steering", in which case you should set this to "PiggybackMode". ``CoreasReader`` includes the following parameters: - **AddToExistingGCD**: If ``True``, the respective radio data will instead be added to the G, C, and D frames if they already exist in the tray. - **DirectoryList**: A list of directories of CoREAS showers, each in their own directory as defined in :ref:`secCoreasSimulations` - **MakeDAQFrames**: If ``True``, the Q frames will be populated with the radio data, electric fields, even headers, etc. - **MakeGCDFrames**: If ``True``, will make the G, C, and D frames and put them in the tray. The geometry will be set by the first passed in simulation's .list file. - **MakeGFrameForEach**: If ``True``, each event will have its own geometry frame made. This is useful of the geometry depends on the event trajectory. - **PiggybackMode**: This mode is used if there is another steering module. In this case, ``CoreasReader`` can ``AddToExistingGCD`` and/or ``MakeDAQFrames``, but it will not ``MakeDAQFrames``. The intended use cases for ``CoreasReader`` are: - Make only a radio simulation, beginning with a tray with nothing in it: ``MakeGCDFrames = MadeDAQFrames = True`` - Make only a GCD file starting with an empty tray: ``MakeGCDFrames = True`` - Add the radio data to a GCD file: ``AddToExistingGCD = True`` - Perform a combined simulation of radio plus other arrays using a single simulated shower. In this case the other arrays would need to specify a GCD file beforehand since they cannot make them on the fly. One should set ``PiggybackMode = MakeDAQFrames = True`` and ``CoreasReader`` should come after the steering module in the tray. - Read in simulations for a star-shaped array where the antenna locations change based on the exact trajectory of the shower. ``MakeGCDFrames = MakeGFrameForEach = MadeDAQFrames = True`` .. _CoREASToAntennaMap: ^^^^^^^^^^^^^^^^^^^ CoREASToAntennaMap ^^^^^^^^^^^^^^^^^^^ This module converts an ``EFieldTimeSeriesMap`` to a ``AntennaDataMap``. This is a utility module which is used only for testing or in the rare cases that an algorithm works only on an ``AntennaDataMap``. ``CoREASToAntennaMap`` includes the following parameters: - **InputName**: Name of the ``I3AntennaDataMap`` to be analyzed in the frame - **OutputName**: Name that the resultant ``EFieldTimeSeriesMap`` will be placed in the frame .. _EFieldCalculator: ^^^^^^^^^^^^^^^^^ EFieldCalculator ^^^^^^^^^^^^^^^^^ This module is the opposite of ChannelInjector_. It solves the dot-product of voltage = (E-field) * (Vector effective length) to get the E-Field from the measured field in both channels. The simulated primary particle is read from the frame and taken to be the arrival direction of the electric field. The module puts an ``EFieldTimeSeriesMap`` into the frame with the E-field components. .. note:: The Poynting vector is not, in general, parallel to the shower axis, being off by a degree or so. Thus if you run ChannelInjector_ followed by EFieldCalculator_, you will not end up exactly where you started. However, without making this approximation, calculating the 3-component E-field cannot be done with the two polarization measurements. ``EFieldCalculator`` includes the following parameters: - **AntennaResponseName**: Name of the ``I3AntennaResponse`` service in the frame - **InputName**: Name of the ``I3AntennaDataMap`` to be analyzed in the frame - **OutputName**: Name that the resultant ``EFieldTimeSeriesMap`` will be placed in the frame .. _ElectronicResponseAdder: ^^^^^^^^^^^^^^^^^^^^^^^^ ElectronicResponseAdder ^^^^^^^^^^^^^^^^^^^^^^^^ This module convolves the response of the various electronics with an input signal (typically, a simulated air shower or background). The module is relatively simple as it just passes the requested ``I3AntennaDataMap`` to the ``I3ElectronicsResponse`` to do all the required calculations to convolve the electronics response. ``ElectronicsResponseAdder`` includes the following parameters: - **ElectronicsResponse**: Name of the ``I3ElectronicsResponse`` service in the context - **GeometryName**: Name of the ``I3Geometry`` that has antennas in the frame - **InputName**: Name of the ``I3AntennaDataMap`` in the frame to add the response to - **OutputName**: Name that the resultant ``I3AntennaDataMap`` will be placed in the frame .. _ElectronicResponseRemover: ^^^^^^^^^^^^^^^^^^^^^^^^^^ ElectronicResponseRemover ^^^^^^^^^^^^^^^^^^^^^^^^^^ This module is simply the inverse module of the ElectronicResponseAdder_. Again, it simply relies on the ``I3ElectronicsResponse`` service to do all the heavy lifting. ``ElectronicResponseRemover`` includes the following parameters: - **ElectronicsResponse**: Name of the ``I3ElectronicsResponse`` service in the context - **GeometryName**: Name of the ``I3Geometry`` that has antennas in the frame - **InputName**: Name of the ``I3AntennaDataMap`` in the frame of which the electronics response will be removed - **OutputName**: Name that the resultant ``I3AntennaDataMap`` will be placed in the frame .. _EstimateRadioShower: ^^^^^^^^^^^^^^^^^^^^ EstimateRadioShower ^^^^^^^^^^^^^^^^^^^^ This module is still under development. It will contain a few calculations to estimate the geometry of the shower. The direction will be estimated by fitting 3 (or more, see below) antennas to a plane front. The core location is taken to be the barycenter of the amplitude in the stations. ``EstimateRadioShower`` includes the following parameters: - **AntennaBadList**: Name of the list of antennas (``I3VectorOMKey``) in the frame which will be ignored during estimation - **InputName**: Name of the antenna data (``I3AntennaDataMap``) in the frame - **HeightAboveBackground**: If ``UseOnlyTopThree = False``, this setting will be used to determine the minimum about an antenna's signal must be above background to be used in the estimation. - **OutputName**: Name of the ``I3Particle`` in the frame - **UseOnlyTopThree**: If ``True``, only the three antennas with the largest signal will be used in the estimation .. _MedianFrequencyFilter: ^^^^^^^^^^^^^^^^^^^^^^ MedianFrequencyFilter ^^^^^^^^^^^^^^^^^^^^^^ This module applies a sort of averaging to the input ``I3AntennaDataMap``. A sliding window of the specified size (in bins) is used to calculate a moving median of the frequency spectrum. The ``FilterWindowWidth`` is the full size of the window and thus the window extends (+/- size/2). ``MedianFrequencyFilter`` includes the following parameters: - **FilterWindowWidth**: Width of the sliding window, in bins, over which the filter will be applied. Value must be >2. - **InputName**: Name of the ``I3AntennaDataMap`` in the frame to which the median filter will be applied - **OutputName**: Name that the resultant ``I3AntennaDataMap`` will be placed in the frame .. _PedestalRemover: ^^^^^^^^^^^^^^^^^^^^^^ PedestalRemover ^^^^^^^^^^^^^^^^^^^^^^ This module takes the data from the pole (or simulations) which is in ADC units. It removes the constant offset of the waveforms and, if requested, will convert the signals to voltage. So the ``PedestalRemover`` simply undoes the math performed in the digitization process (see ``I3ElectronicsResponse``). ``PedestalRemover`` includes the following parameters: - **ConvertToVoltage**: If ``True`` the waveform is converted from ADC counts to voltage after removing the pedestal - **ElectronicsResponse**: Name of the ``I3ElectronicsResponse`` service in the context - **InputName**: Name of the ``I3AntennaDataMap`` in the frame whose pedestal will be removed - **OutputName**: Name that the resultant ``I3AntennaDataMap`` will be placed in the frame .. _TraceResampler: ^^^^^^^^^^^^^^^^^^^^^^ TraceResampler ^^^^^^^^^^^^^^^^^^^^^^ The ``TraceResampler`` module upsamples/thins out the time trace to the specified binning. For instance, the default time binning of CoREAS is 0.2 ns. However, the binning of the digitizer might be less fine, :math:`\sim` 1 ns. This module essentially just relies on the ``ResamplingTools`` to do all of the hard lifting. You can give this module either an ``EFieldTimeSeriesMap`` or an ``I3AntennaDataMap`` and it will place the same data type back into the frame after resampling. For more about this algorithm, see :ref:`waveform_resampling`. ``TraceResampler`` includes the following parameters: - **InputName**: Name of the ``EFieldTimeSeriesMap`` or ``I3AntennaDataMap`` in the frame to be resampled - **OutputName**: Name that the resultant ``I3AntennaDataMap`` will be placed in the frame - **ResampledBinning**: Requested time-step that the ``I3AntennaDataMap`` will be resampled to. .. _WaveformChopper: ^^^^^^^^^^^^^^^^^^^^^^ WaveformChopper ^^^^^^^^^^^^^^^^^^^^^^ This module simply truncates the traces for all antennas to the binnings requested length. This module works similarly to how a "slice" is done in python. ``WaveformChopper`` includes the following parameters: - **ApplyInDAQ**: If ``True``, the truncating will be performed in the Q-frame, otherwise the P-frame - **InputName**: Name of the ``I3AntennaDataMap`` in the frame to chop - **OutputName**: Name that the resultant ``I3AntennaDataMap`` will be placed in the frame - **MinBin**: Traces will now start at the bin specified - **MaxBin**: Traces will now end at the bin specified Note that this means that the traces will have ``MaxBin - MinBin + 1`` entries after running this module. The code will throw and error if you request a bin range that is outside of the available range. .. _WaveformDigitizer: ^^^^^^^^^^^^^^^^^^^^^^ WaveformDigitizer ^^^^^^^^^^^^^^^^^^^^^^ This module also leans heavily on the ``I3ElectronicsResponse`` service to give the conversions from voltage to ADC counts. However, this module can also add the internal TAXI noise (if selected in the ``I3ElectronicsResponse``). For each channel, a noise trace is read in from file, re-sampled if the binning of the TAXI trace does not match the signal's and converted to voltage. The this sum is finally converted to ADC counts (and saturation is taken into account if selected in the response service) and put in the frame. ``WaveformDigitizer`` includes the following parameters: - **InputName**: Name of the ``I3AntennaDataMap`` in the frame to add the digitize - **OutputName**: Name that the resultant ``I3AntennaDataMap`` will be placed in the frame - **ElectronicsResponse**: (Required) Name of the ``I3ElectronicsResponse`` service in the context .. _ZeroPadder: ^^^^^^^^^^^^^^^^^^^^^^ ZeroPadder ^^^^^^^^^^^^^^^^^^^^^^ This module also leans heavily on the ``I3ElectronicsResponse`` service to give the conversions from voltage to ADC counts. However, this module can also add the internal TAXI noise (if selected in the ``I3ElectronicsResponse``). For each channel, a noise trace is read in from file, re-sampled if the binning of the TAXI trace does not match the signal's and converted to voltage. The this sum is finally converted to ADC counts (and saturation is taken into account if selected in the response service) and put in the frame. You can give this module either an ``EFieldTimeSeriesMap`` or an ``I3AntennaDataMap`` and it will place the same data type back into the frame after padding. ``ZeroPadder`` includes the following parameters: - **AddToFront**: If ``True``, the zeros will be appended to the front of the time-series/spectrum, otherise they will be added to the back. - **AddToTimeSeries**: If ``True``, the zeros will be appended to the front/back of the time-series. Otherwise, they will be appended to the spectrum. - **AppendN**: If this is set, then the module will append exactly this many bins worth of zeros. (Incompatible with FixedLength option.) - **ApplyInDAQ**: If ``True``, the truncating will be performed in the Q-frame, otherwise the P-frame - **FixedLength**: If this is set, zeros will be added such that the time-series/spectrum is exactly this long. (Incompatible with AppendN option.) - **InputName**: Name of the ``I3AntennaDataMap`` in the frame to add the digitize - **OutputName**: Name that the resultant ``I3AntennaDataMap`` will be placed in the frame .. _services: -------- Services -------- .. _I3ElectronicsResponseFactory: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ I3ElectronicsResponseFactory ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This service installs a copy of ``I3ElectronicsResponse`` into the context. It can be used to add/remove the effects of electrical components on an RF signal. The ``ElectronicsResponseFactory`` includes the following parameters: - **AntennaType**: The type of antenna whose LNA will be used (see ``enum`` in ``RadUtility.h``) - **AdditionalGain**: An additional amount of amplitfication will be applied to the Radioboard's response. Values should be given in dB. - **ADCPedestalVolage**: Ideally the digitized traces would sit in the middle of the ADC range. This setting allows you to shift the digitized traces up or down by the specified voltage first (see WaveformDigitizer_). - **ADCVoltageRange**: Range of the ADC, if set to :math:`X`, this means that the digitizer ranges from :math:`+X` to :math:`-X` (see WaveformDigitizer_). - **CableLength**: The length of the cables to use (affects attenuation amplitude) - **CableTemperature**: The temperature of the cables (affects attenuation amplitude) - **IncludeBiasTee**: If ``True``, the bias-tee's response will be included - **IncludeCables**: If ``True``, the cables's response will be included - **IncludeElectronicNoise**: If included, when the signal is digitized (see WaveformDigitizer_), the measured TAXI traces will be linearly added to the simulated ones. - **IncludeLNA**: If ``True``, the LNA's response will be included - **IncludeRadioBoard**: If ``True``, the radioboard's response will be included - **IncludeRadioBoardNoise**: If ``True``, this will use the noise of TAXI and the radio-board - **IncludeSaturation**: If ``True`` the ADC will be truncated below 0 or above :math:`2^\texttt{NADCBits}``, see equations above. - **IncludeTaxi**: If ``True``, TAXI's response will be included - **InstallServiceAs**: The name by which modules/services can find this service in the tray. - **NADCBits**: Number of bits that the digitizer has - **OverrideHeadDir**: The user can specify a default directory to look into for the radio response files. Note that they must be in an expected format, so this is not recommended unless you know what you are doing. However, this is useful if you want to work outside the cluster. Note that ``I3ElectronicsResponse`` needs to load data tables that are normally stored in CVMFS. If you do not have access to CVMFS on the machine you are using to run this code, you must download the files, see :ref:`acquiringRadcubeFiles`. Finally, note that the ``I3ElectronicsResponse`` can also be used as a stand-alone class. For an example of this see ``$I3_BUILD/radcube/resources/examples/ExampleScript_ElectronicsResponse.py``. .. _I3AntennaResponseFactory: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ I3AntennaResponseFactory ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This service installs an instance of ``I3AntennaResponse`` into the context. ``I3AntennaResponseFactory`` includes the following parameters: - **AntennaType**: The type of antenna whose LNA will be used (see ``enum`` in ``I3RadUtilities.h``) - **OverrideHeadDir**: The user can specify a default directory to look into for the radio response files. Note that they must be in an expected format, so this is not recommended unless you know what you are doing. however, this is useful if you want to work outside the cluster. - **InstallServiceAs**: The name by which modules/services can find this service in the tray. Note that ``I3AntennaResponse`` needs to load data tables that are normally stored in CVMFS. If you do not have access to CVMFS on the machine you are using to run this code, you must download the files, see :ref:`acquiringRadcubeFiles`. .. _segments: ------------------- Segments ------------------- The segments are strings of :ref:`radcube` modules which are used to perform a "standard", or at least recommended, set of actions. The current ones are listed below (see ``$I3_SRC/radcube/python/segments``). .. _RadioInjection: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RadioInjection ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The radio injection segment performs a combination of the module above to perform the complete simulation of an air shower event. It reads in a list of event locations, creates the GCD files, injects them into the antenna, adds noise, convolves it with the electronics' responses, and digitizes it. At the conclusion of this segment the data should be in the exact same format as what would arrive from the pole. That is, nothing more need be added to the Q frame to run any script you would run on real data. ``RadioInjection`` has the following parameters: - **InputFiles**: List of directories, each containing one CoREAS simulation - **ElectronicServiceName**: Name of the I3ElectronicsService in the frame - **AntennaServiceName** Name of the I3AntennaService in the frame - **RandomServiceName**: Name of the random number generation service in the frame - **MakeGCD**: If ``True``, the GCD files will be made - **ThermalNoiseTemp**: Set the thermal noise temperature to be simulated - **OutputName**: Name of the I3AntennaDataMap to be put into the frame at the conclusion of this - **PiggybackMode**: If this is not the main steering module, set this to ``True`` (see CoreasReader_) .. _RadioReconPrep: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RadioReconPrep ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This segment runs a number of modules which take the simulated or real data, analayzes it, and prepares it for a reconstruction. - **InputFiles**: List of directories, each containing one CoREAS simulation - **ElectronicServiceName**: Name of the I3ElectronicsService in the frame - **OutputName**: Name of the I3AntennaDataMap to be put into the frame at the conclusion of this - **BandwidthLimits**: The data is filtered on a bandpass with these limits (low, high) - **EstimateShower**: If ``True`` the shower properies are estimated and an ``I3Particle`` is put in the frame. .. rubric:: Footnotes .. [#thermalnoisenote] In this case, a thermal noise is taken to be the equivalent noise temperature, flat in frequency space, as opposed to a black-body spectrum with a given temperature, which would follow Planck's Law of Radiation. .. [#linearresponsenote] As opposed to having some interplay between the components. .. [#extrapolationnote] This design choice was made to avoid extrapolating the responses, unbeknownst to the user.