Accessing unit test data¶
Striptease implements a few functions to download and access the data acquired during the unit tests of the Strip polarimeters. These tests were done at the cryogenic laboratory of the University of Milan Bicocca, and they are used as reference in some of the system-level tests. The tests are currently available at https://striptest.fisica.unimi.it/unittests/; the library provides a simple interface to download the data from there and load them into Python objects.
Here is an example that shows how to use these functionalities:
import striptease.unittests as u
# Download the test with ID #354 from the web server. This might
# take a few seconds…
test = u.get_unit_test(354)
# …but if you ask for it again, it will use a local cache and will
# return the value instantly
_ = u.get_unit_test(354)
# The result of the call to "u.get_unit_test" is a UnitTest object
print(type(test))
# Output:
# <class 'striptease.unittests.UnitTest'>
print(f"{test.url}, {test.polarimeter_name}")
# Output:
# https://striptest.fisica.unimi.it/unittests/tests/354, STRIP02
# The "test" variable only contains metadata about the test.
# To actually load the datasets, use "u.load_unit_test_data".
# It returns the actual data from the HDF5 file itself.
data = u.load_unit_test_data(test)
# The type of "data" depends on the test; it can either be a
# "UnitTestDC" class or a "UnitTestTimestream" class.
print(type(data))
# Output:
# <class 'striptease.unittests.UnitTestDC'>
As you see in the example, there are two functions to access the test
data: the first one, get_unit_test()
, downloads the metadata
for a test, while the second one, load_unit_test_data()
,
download the full data. As the second one can take some time, if you
are just interested in the general characteristics of the test (e.g.,
when the test was done, or on which polarimeter) you should call just
get_unit_test()
.
-
striptease.
get_unit_test
(test_num: int, server='https://striptest.fisica.unimi.it', local_cache=PosixPath('/home/docs/.strip/unittests/unittests.db')) → Optional[striptease.unittests.UnitTest][source]¶ Return a
UnitTest
object referring to a unit test.This function is used to access the data files acquired during the Strip Unit Tests done in Milano Bicocca. Each test is referenced by an unique number, which is passed in the parameter test_num. The parameter server must be a string containing the name of the web server hosting the test database. The parameter local_cache points to a file that will contain a local copy of each test downloaded from the webserver.
The following code prints some information about test #354:
from striptease.unittests import get_unit_test test = get_unit_test(354) print(f"The test was acquired on {test.acquisition_date}")
Once you retrieve the information for a test, you can use
load_unit_test_data()
to load the actual data acquired during the test.Parameters: - test_num (int) – the unique ID of the unit test to download
- server (str) – the protocol+name/IP address of the web server
that hosts the unit tests. The default is the variable
DEFAULT_UNIT_TEST_SERVER
, and it should probably be ok for any situation. - local_cache (Path) – the path to a file that will contain a local copy of each test downloaded using this function. This speeds up subsequent queries to the same test.
Returns: An instance of
UnitTest
.
-
striptease.
load_unit_test_data
(input_file: Union[str, pathlib.Path, striptease.unittests.UnitTest]) → Union[striptease.unittests.UnitTestTimestream, striptease.unittests.UnitTestDC][source]¶ Load an HDF5 file into a Timestream object
Return either an instance of the class
UnitTestTimestream
orUnitTestDC
. The choice between the two types depends on the type of the test (i.e., the value of the keytest_type
in themetadata
of the test):- DC tests return a
UnitTestDc
; these tests were acquired by directly sampling the biases at the components of the polarimeters, and no proper time streams were recorded. - All other types of tests return a
UnitTestTimestream
.
The typical usage for this function is to call it on the result of a call to
get_unit_test()
, as in the following example:import striptease.unittests as u test = u.get_unit_test(354) data = load_unit_test_data(test)
Parameters: input_file – Either a string containing the path to a HDF5 file, a pathlib.Path
object, or aUnitTest
object.Returns: (1) a dictionary containing a set of attributes read from the root object of the HDF5 file, and (2) either an instance of the class UnitTestTimestream
orUnitTestDC
, depending on the type of the test.Return type: A pair containing two elements - DC tests return a
The type of the return value of the function
load_unit_test_data()
depends on the kind of test. During the
unit tests in the cryogenic laboratory of the University of Milano
Bicocca, tests were grouped in two categories:
- DC tests exercised every single component of each polarimetric unit.
They were done using an apparatus that provided biases and measured
currents and voltages. Data acquired during this kind of test is
stored in a
UnitTestDC
object. - The tests that exercised the polarimeter as a whole used a different
acquisition system, which was able to record the timing of each
measurement. Data acquired during this kind of test is stored in a
UnitTestTimestream
object.
In the next chapters we detail the structure of the two classes
UnitTestDC
and UnitTestTimestream
.
-
class
striptease.
UnitTest
(url: str = '', metadata: Dict[str, Any] = <factory>, hdf5_file_path: pathlib.Path = PosixPath('.'))[source]¶ Information about a polarimetric unit test
This class hold some information about the data of a polarimetric unit test ran in Bologna, and it is returned by the function
get_unit_test()
. It contains the following fields:url
: a string containing the base URL of the testmetadata
: a dictionary containing the JSON record downloaded from the web server. This dictionary contains many details about the test itself: the name of the operators that actually executed the test, the date when the data was acquired, etc.hdf5_file_path
: apathlib.Path
object pointing to the HDF5 file saved in the local cache. Instead of accessing this file directly, you should instead callload_unit_test_data()
.
-
class
striptease.
UnitTestDC
(acquisition_date: datetime.date, band: str, is_cryogenic: bool, polarimeter_name: str, url: str, components: Dict[str, striptease.unittests.UnitTestDCCurves] = <factory>)[source]¶ Detailed information about a unit-level DC test of a polarimeter.
This class is created by the function
load_unit_test_data()
whenever a DC test is requested. It contains the following fields:acquisition_date
: adatetime.date
object containing the date when the test was acquired.band
: a string containing eitherQ
orW
;is_cryogenic
: a Boolean value indicating whether the test was done in cryogenic or warm conditions;polarimeter_name
: the name of the polarimeter being tested (e.g.,STRIP02
);url
: a string containing the URL of the test pagecomponents
: a dictionary associating the name of each component of the polarimeter (e.g.,HA1
for the first amplifier of the first leg) with aUnitTestDCCurves
object, which contains the data of the various curves characterizing the polarimetric component.
-
class
striptease.
UnitTestTimestream
(acquisition_date: datetime.date, band: str, is_cryogenic: bool, polarimeter_name: str, url: str, time_s: Any = None, pctime: Any = None, phb: Any = None, record: Any = None, demodulated: Any = None, power: Any = None, rfpower_db: Any = None, freq_hz: Any = None)[source]¶ A time stream acquired from one polarimeter during the Unit Level tests in Bicocca.
This class is created by the function
load_unit_test_data()
whenever the caller asks to load a unit-level test where a timestream is acquired (e.g., bandpass measurement, noise temperature characterization, etc.). It contains the following fields:acquisition_date
: adatetime.date
object containing the date when the test was acquired.band
: a string containing eitherQ
orW
;is_cryogenic
: a Boolean value indicating whether the test was done in cryogenic or warm conditions;polarimeter_name
: the name of the polarimeter being tested (e.g.,STRIP02
);url
: a string containing the URL of the test pagetime_s
: A NumPy array containing the time in secondspctime
: A NumPy array containing the On-board time, in clock ticksphb
: A NumPy array containing the phase of the slow phase switchrecord
: A NumPy array containing an undocumented fielddemodulated
: A 4×N NumPy matrix containing the output of- DEM0, DEM1, DEM2, DEM3 channels
power
: A 4×N NumPy matrix containing the output of PWR0,- PWR1, PWR2, PWR3 channels
rfpower_db
: A NumPy array containing the power of the- -radiofrequency generator, in dB, or 1 if turned off
freq_hz
: A NumPy array containing the frequency of the- signal injected by the radiofrequency generator, in Hertz. If the generator is turned off, this is -1.
Single-component tests¶
Single-component tests, also known as «DC tests», are represented by
an instance of the class UnitTestDC
. The class provides the
data measured while exercising each of the components in the
components
field, which is an instance of the class
UnitTestDCCurves
. You can think of both classes as wrappers
to dict
types.
Here is an example, using test #354 as a testbed:
import striptease.unittests as u
import matplotlib.pylab as plt
data = u.load_unit_test_data(u.get_unit_test(354))
ha1_ivdv_data = data.components['HA1'].curves['IDVD']
_, axes = plt.subplots(nrows=3, figsize=(6, 14))
axes[0].plot(
ha1_ivdv_data['DrainV'],
ha1_ivdv_data['DrainI'],
)
axes[0].set_title(r'$V_d \times I_d$ curves for HA1')
axes[0].set_xlabel('Drain voltage')
axes[0].set_ylabel('Drain current')
axes[1].plot(ha1_ivdv_data['GateI'], '.')
axes[1].set_ylabel('Gate current')
axes[2].plot(ha1_ivdv_data['GateV'], '.')
axes[2].set_ylabel('Gate voltage')
The result is the following plot:
Note that in this test the drain current and voltage were measured every time the gate biases were changed. The actual behavior of the data depends of course on the component and the test being done.
Polarimetric tests (timelines)¶
Timeline data acquired during a Strip unit test is stored in objects
of type UnitTestTimestream
. The following example shows how
to plot the demodulated data acquired during test #355 (STRIP02):
import striptease.unittests as u
import matplotlib.pylab as plt
data = u.load_unit_test_data(u.get_unit_test(355))
_, axes = plt.subplots(nrows=4, figsize=(6, 17))
# Plot the output of DEM0, DEM1, DEM2, and DEM3
for i in range(4):
axes[i].plot(data.time_s, data.demodulated[:, i])
axes[i].set_xlabel("Time [s]")
axes[i].set_ylabel("Signal [ADU]")
And here is the result:
Other information¶
There are a few other functions implemented by the framework that you might find useful, e.g., when you are producing a report and want to put links to a unit test you used in your calculations.
-
striptease.
unit_test_url
(test_num: int, server='https://striptest.fisica.unimi.it') → str[source]¶ Return a string containing the URL of a unit-level test
How caching works¶
Every time the function get_unit_test()
is called, it saves a
copy of the HDF5 file and the metadata downloaded from the unit test
webserver into a hidden directory within the home folder of the
current user. The metadata are saved in a SQLite3 database, and the
HDF5 file is saved within the same folder.
The path to the SQLite3 database can be accessed using the constant
DEFAULT_UNIT_TEST_CACHE_PATH
. However, you will probably never
need to mess with this directory, as it is handled internally by the
library.