emccd-detect 2.3.0__py3-none-any.whl → 2.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
emccd_detect/__init__.py CHANGED
@@ -1,2 +1,2 @@
1
1
  # -*- coding: utf-8 -*-
2
- __version__ = '2.3.0'
2
+ __version__ = '2.5.0'
@@ -6,13 +6,14 @@ import warnings
6
6
  from pathlib import Path
7
7
 
8
8
  import numpy as np
9
+ from astropy.io import fits
9
10
 
10
11
  from emccd_detect.cosmics import cosmic_hits, sat_tails
11
12
  from emccd_detect.rand_em_gain import rand_em_gain
12
13
  from emccd_detect.nonlinearity import apply_relgains
13
14
  from emccd_detect.util.read_metadata_wrapper import MetadataWrapper
14
15
  try:
15
- from arcticpy import add_cti, CCD, ROE, Trap, TrapInstantCapture
16
+ from arcticpy import add_cti, CCD, ROE, TrapInstantCapture
16
17
  except:
17
18
  pass
18
19
 
@@ -54,7 +55,12 @@ class EMCCDDetectBase:
54
55
  inclusive.
55
56
  numel_gain_register : int
56
57
  Number of gain register elements. For eventually modeling partial CIC.
57
-
58
+ row_read_time : float
59
+ Time in seconds for each row to move into the first register (same as
60
+ the time for each row to be clocked toward the register). This is used
61
+ to simulate smear on the image due to clocking during the exposure to
62
+ light. Especially useful for shutterless EMCCDs. If 0, no smear is
63
+ simulated.
58
64
  """
59
65
  def __init__(
60
66
  self,
@@ -70,7 +76,8 @@ class EMCCDDetectBase:
70
76
  pixel_pitch,
71
77
  eperdn,
72
78
  nbits,
73
- numel_gain_register
79
+ numel_gain_register,
80
+ row_read_time
74
81
  ):
75
82
  # Input checks
76
83
  if not isinstance(nbits, (int, np.integer)):
@@ -78,6 +85,8 @@ class EMCCDDetectBase:
78
85
  if nbits < 1 or nbits > 64:
79
86
  raise EMCCDDetectException('nbits must be between 1 and 64, '
80
87
  'inclusive')
88
+ if row_read_time < 0:
89
+ raise EMCCDDetectException('row_read_time must be >= 0 seconds.')
81
90
 
82
91
  self.em_gain = em_gain
83
92
  self.full_well_image = full_well_image
@@ -92,14 +101,18 @@ class EMCCDDetectBase:
92
101
  self.eperdn = eperdn
93
102
  self.nbits = nbits
94
103
  self.numel_gain_register = numel_gain_register
104
+ self.row_read_time = row_read_time
95
105
 
96
106
  # Placeholders for trap parameters
97
- self.ccd = None
98
- self.roe = None
99
- self.traps = None
100
- self.express = None
101
- self.offset = None
102
- self.window_range = None
107
+ self.parallel_ccd = None
108
+ self.parallel_roe = None
109
+ self.parallel_traps = None
110
+ self.parallel_express = None
111
+ self.serial_ccd = None
112
+ self.serial_roe = None
113
+ self.serial_traps = None
114
+ self.serial_express = None
115
+
103
116
 
104
117
  # Placeholders for derived values
105
118
  self.mean_expected_rate = None
@@ -123,36 +136,72 @@ class EMCCDDetectBase:
123
136
  try:
124
137
  def update_cti(
125
138
  self,
126
- ccd=None,
127
- roe=None,
128
- traps=None,
129
- express=1,
130
- offset=0,
131
- window_range=None
139
+ parallel_ccd=None,
140
+ parallel_roe=None,
141
+ parallel_traps=None,
142
+ parallel_express=1,
143
+ serial_ccd=None,
144
+ serial_roe=None,
145
+ serial_traps=None,
146
+ serial_express=1,
147
+ parallel=True,
148
+ serial=True,
149
+ **kwargs # any other arguments that arcticpy.add_cti() might accept
132
150
  ):
151
+ '''See arcticpy documentation for details on parameters. Any arguments
152
+ not explicitly listed here can be handed to arcticpy.add_cti() via
153
+ kwargs.
154
+
155
+ Parallel and serial CTI can each be switched on or off via the
156
+ "parallel" and "serial" arguments of this function. True means that
157
+ type of CTI is simulated. Both are True by default.'''
133
158
  # Update parameters
134
- self.ccd = ccd
135
- self.roe = roe
136
- self.traps = traps
137
-
138
- self.express = express
139
- self.offset = offset
140
- self.window_range = window_range
159
+ self.parallel_ccd = parallel_ccd
160
+ self.parallel_roe = parallel_roe
161
+ self.parallel_traps = parallel_traps
162
+ self.parallel_express = parallel_express
163
+ self.serial_ccd = serial_ccd
164
+ self.serial_roe = serial_roe
165
+ self.serial_traps = serial_traps
166
+ self.serial_express = serial_express
167
+ self.kwargs = kwargs
168
+ self.parallel = parallel
169
+ self.serial = serial
141
170
 
142
171
  # Instantiate defaults for any class instances not provided
143
- if self.ccd is None:
144
- self.ccd = CCD()
145
- if roe is None:
146
- self.roe = ROE()
147
- if traps is None:
172
+
173
+ if parallel_ccd is None:
174
+ self.parallel_ccd = CCD()
175
+ if parallel_roe is None:
176
+ self.parallel_roe = ROE()
177
+ if parallel_traps is None:
148
178
  #self.traps = [Trap()]
149
- self.traps = [TrapInstantCapture()]
179
+ self.parallel_traps = [TrapInstantCapture()]
180
+ if self.parallel is False: # overrides
181
+ self.parallel_ccd = None
182
+ self.parallel_roe = None
183
+ self.parallel_traps = None
184
+
185
+ if serial_ccd is None:
186
+ self.serial_ccd = CCD()
187
+ if serial_roe is None:
188
+ self.serial_roe = ROE()
189
+ if serial_traps is None:
190
+ self.serial_traps = [TrapInstantCapture()]
191
+ if self.serial is False: #overrides
192
+ self.serial_ccd = None
193
+ self.serial_roe = None
194
+ self.serial_traps = None
150
195
 
151
196
  def unset_cti(self):
197
+ '''This turns off all CTI implementation.'''
152
198
  # Remove CTI simulation
153
- self.ccd = None
154
- self.roe = None
155
- self.traps = None
199
+ self.parallel_ccd = None
200
+ self.parallel_roe = None
201
+ self.parallel_traps = None
202
+ self.serial_ccd = None
203
+ self.serial_roe = None
204
+ self.serial_traps = None
156
205
  except:
157
206
  pass
158
207
 
@@ -207,6 +256,43 @@ class EMCCDDetectBase:
207
256
  return output_dn.reshape(actualized_e.shape)
208
257
 
209
258
  def integrate(self, fluxmap_full, frametime, exposed_pix_m):
259
+ # apply non-uniformity of pixel responsivity via master flat
260
+ if hasattr(self, 'flat_path'):
261
+ if self.flat_path is not None:
262
+ with fits.open(self.flat_path) as hdul:
263
+ self.flat = hdul[1].data
264
+ if (self.flat < 0).any():
265
+ raise EMCCDDetectException('Master flat must not contain '
266
+ 'negative values.')
267
+ if self.flat.shape != fluxmap_full.shape:
268
+ imaging_area_ones = np.ones_like(fluxmap_full)
269
+ # Attempt to embed the flat within the
270
+ # imaging+shielded area
271
+ self.flat_im = self.meta.embed_im(imaging_area_ones,
272
+ 'image', self.flat.copy())
273
+ if self.flat_im.shape != fluxmap_full.shape:
274
+ raise EMCCDDetectException('Master flat shape must '
275
+ 'agree with shape of fluxmap.')
276
+ else:
277
+ fluxmap_full *= self.flat_im
278
+ else:
279
+ fluxmap_full *= self.flat
280
+
281
+ # simulate smear to fluxmap
282
+ # credit for this smearing code: Peter Williams, Tellus1, 2024
283
+ # XXX Technically, smearing adds electrons to each pixel, which
284
+ # increases the chance of charge capture for CTI, but simulating
285
+ # this small effect would require hacking arCTIc.
286
+ smear = np.zeros_like(fluxmap_full)
287
+ m = len(smear)
288
+ for r in range(m):
289
+ columnsum = 0
290
+ for i in range(r+1):
291
+ columnsum = columnsum + self.row_read_time*fluxmap_full[i,:]
292
+ smear[r,:] = columnsum
293
+
294
+ fluxmap_full = fluxmap_full + smear/frametime
295
+
210
296
  # Add cosmic ray effects
211
297
  # XXX Maybe change this to units of flux later
212
298
  cosm_actualized_e = cosmic_hits(np.zeros_like(fluxmap_full),
@@ -225,16 +311,26 @@ class EMCCDDetectBase:
225
311
 
226
312
  def clock_parallel(self, actualized_e):
227
313
  # Only add CTI if update_cti has been called
228
- if self.ccd is not None and self.roe is not None and self.traps is not None:
229
- parallel_counts = add_cti(
230
- actualized_e.copy(),
231
- parallel_roe=self.roe,
232
- parallel_ccd=self.ccd,
233
- parallel_traps=self.traps,
234
- parallel_express=self.express,
235
- parallel_offset=self.offset,
236
- parallel_window_range=self.window_range
237
- )
314
+ if self.parallel_ccd is not None and self.parallel_roe is not None and self.parallel_traps is not None:
315
+ try:
316
+ parallel_counts = add_cti(
317
+ actualized_e.copy(),
318
+ parallel_roe=self.parallel_roe,
319
+ parallel_ccd=self.parallel_ccd,
320
+ parallel_traps=self.parallel_traps,
321
+ parallel_express=self.parallel_express,
322
+ **self.kwargs
323
+ )
324
+ except:
325
+ parallel_counts = add_cti(
326
+ actualized_e.copy(),
327
+ parallel_roe=self.parallel_roe,
328
+ parallel_ccd=self.parallel_ccd,
329
+ parallel_traps=self.parallel_traps,
330
+ parallel_express=self.parallel_express,
331
+ parallel_window_range=0,
332
+ **self.kwargs
333
+ )
238
334
  else:
239
335
  parallel_counts = actualized_e
240
336
 
@@ -242,12 +338,37 @@ class EMCCDDetectBase:
242
338
 
243
339
  def clock_serial(self, actualized_e_full, empty_element_m):
244
340
  # Actualize cic electrons in prescan and overscan pixels
245
- # XXX Another place where we are fudging a little
341
+ # XXX Another place where we are fudging a little as far as the order of operations(?)
246
342
  actualized_e_full[empty_element_m] = np.random.poisson(actualized_e_full[empty_element_m]
247
343
  + self.cic)
248
- # XXX Call arcticpy here
344
+
345
+ # add serial CTI; the addition of CIC (serial and parallel) is really
346
+ # *during* the addition of CTI, but this corrective effect would not be very significant
347
+ if self.serial_ccd is not None and self.serial_roe is not None and self.serial_traps is not None:
348
+ try:
349
+ cti_actualized_e_full = add_cti(
350
+ actualized_e_full.copy(),
351
+ serial_roe=self.serial_roe,
352
+ serial_ccd=self.serial_ccd,
353
+ serial_traps=self.serial_traps,
354
+ serial_express=self.serial_express,
355
+ **self.kwargs
356
+ )
357
+ except:
358
+ cti_actualized_e_full = add_cti(
359
+ actualized_e_full.copy(),
360
+ serial_roe=self.serial_roe,
361
+ serial_ccd=self.serial_ccd,
362
+ serial_traps=self.serial_traps,
363
+ serial_express=self.serial_express,
364
+ serial_window_range=0,
365
+ **self.kwargs
366
+ )
367
+ else:
368
+ cti_actualized_e_full = actualized_e_full
369
+
249
370
  # Flatten row by row
250
- actualized_e_full_flat = actualized_e_full.ravel()
371
+ actualized_e_full_flat = cti_actualized_e_full.ravel()
251
372
 
252
373
  # Clock electrons through serial register elements
253
374
  serial_counts = self._serial_register_elements(actualized_e_full_flat)
@@ -429,7 +550,7 @@ class EMCCDDetect(EMCCDDetectBase):
429
550
  full_well_image : float
430
551
  Image area full well capacity (e-). Defaults to 78000.
431
552
  full_well_serial : float
432
- Serial (gain) register full well capacity (e-). Defaults to None.
553
+ Serial (gain) register full well capacity (e-). Defaults to 105000.
433
554
  dark_current: float
434
555
  Dark current rate (e-/pix/s). Defaults to 0.00031.
435
556
  cic : float
@@ -445,7 +566,7 @@ class EMCCDDetect(EMCCDDetectBase):
445
566
  pixel_pitch : float
446
567
  Distance between pixel centers (m). Defaults to 13e-6.
447
568
  eperdn : float
448
- Electrons per dn. Defaults to None.
569
+ Electrons per dn. Defaults to 8.2.
449
570
  nbits : int
450
571
  Number of bits used by the ADC readout. Must be between 1 and 64,
451
572
  inclusive. Defaults to 14.
@@ -458,15 +579,28 @@ class EMCCDDetect(EMCCDDetectBase):
458
579
  nonlin_path : str
459
580
  Path of nonlinearity correction file. See doc string of
460
581
  nonlinearity.apply_relgains for details on the required
461
- format of the file. If None, defaults to no application of
462
- nonlinearity.
582
+ format of the file. If None, no application of
583
+ nonlinearity is performed. Defaults to None.
584
+ row_read_time : float
585
+ Time in seconds for each row to move into the first register (same as
586
+ the time for each row to be clocked toward the register). This is used
587
+ to simulate smear on the image due to clocking during the exposure to
588
+ light. Especially useful for shutterless EMCCDs. If 0, no smear is
589
+ simulated. Defaults to 0 seconds.
590
+ flat_path : str
591
+ Path of master flat file. Assumed to be a FITS file for which the flat
592
+ data resides in the first extension HDU. The flat is assumed to be
593
+ of image-area shape (specified by the metadata from meta_path),
594
+ dark-subtracted, divided by k-gain, divided by EM gain, and desmeared.
595
+ If the input is None, no application of pixel nonuniformity is
596
+ performed. Defaults to None.
463
597
 
464
598
  """
465
599
  def __init__(
466
600
  self,
467
601
  em_gain=1.,
468
602
  full_well_image=78000.,
469
- full_well_serial=None,
603
+ full_well_serial=105000.,
470
604
  dark_current=0.00031,
471
605
  cic=0.016,
472
606
  read_noise=110.,
@@ -474,11 +608,13 @@ class EMCCDDetect(EMCCDDetectBase):
474
608
  qe=0.9,
475
609
  cr_rate=0.,
476
610
  pixel_pitch=13e-6,
477
- eperdn=None,
611
+ eperdn=8.2,
478
612
  nbits=14,
479
613
  numel_gain_register=604,
480
614
  meta_path=None,
481
- nonlin_path=None
615
+ nonlin_path=None,
616
+ row_read_time=0, # seconds
617
+ flat_path=None
482
618
  ):
483
619
  # If no metadata file path specified, default to metadata.yaml in util
484
620
  if meta_path is None:
@@ -489,13 +625,8 @@ class EMCCDDetect(EMCCDDetectBase):
489
625
  self.meta_path = meta_path
490
626
  self.meta = MetadataWrapper(self.meta_path)
491
627
 
492
- # Set defaults from metadata
493
- if full_well_serial is None:
494
- full_well_serial = self.meta.fwc
495
- if eperdn is None:
496
- eperdn = self.meta.eperdn
497
-
498
628
  self.nonlin_path = nonlin_path
629
+ self.flat_path = flat_path
499
630
 
500
631
  super().__init__(
501
632
  em_gain=em_gain,
@@ -510,7 +641,8 @@ class EMCCDDetect(EMCCDDetectBase):
510
641
  pixel_pitch=pixel_pitch,
511
642
  eperdn=eperdn,
512
643
  nbits=nbits,
513
- numel_gain_register=numel_gain_register
644
+ numel_gain_register=numel_gain_register,
645
+ row_read_time=row_read_time
514
646
  )
515
647
 
516
648
  def sim_full_frame(self, fluxmap, frametime):
@@ -613,6 +745,12 @@ class EMCCDDetect(EMCCDDetectBase):
613
745
  Bias subtracted, gain divided frame in units of e-.
614
746
 
615
747
  """
748
+ if hasattr(self, 'nonlin_path'):
749
+ if self.nonlin_path is not None:
750
+ nonlin_factors = apply_relgains(frame_dn, self.em_gain,
751
+ self.nonlin_path)
752
+ # correct fo nonlin by dividing
753
+ frame_dn = frame_dn/nonlin_factors
616
754
  return (frame_dn * self.eperdn - self.bias) / self.em_gain
617
755
 
618
756
 
@@ -704,7 +842,8 @@ def emccd_detect(
704
842
  pixel_pitch=pixel_pitch,
705
843
  eperdn=1.,
706
844
  nbits=64,
707
- numel_gain_register=604
845
+ numel_gain_register=604,
846
+ row_read_time=0
708
847
  )
709
848
 
710
849
  return emccd.sim_sub_frame(fluxmap, frametime).astype(float)
@@ -4,6 +4,8 @@ pixel of a frame.
4
4
 
5
5
  Relative gain is dependent on both the detector gain and the dn count
6
6
  value of a given pixel.
7
+
8
+ Adapted from https://github.com/roman-corgi/cgi_iit_drp/blob/main/proc_cgi_frame_NTR/proc_cgi_frame/gsw_nonlin.py.
7
9
  """
8
10
 
9
11
  import numpy as np
@@ -50,11 +50,4 @@ geom:
50
50
  cols: 56
51
51
  r0c0:
52
52
  - 0
53
- - 2144
54
- eperdn: 8.2
55
- fwc: 105000 #serial
56
- sat_thresh: 0.99
57
- plat_thresh: 0.85
58
- cosm_filter: 2
59
- tail_filter: #5
60
- cic_thresh: #100
53
+ - 2144
@@ -22,20 +22,6 @@ class Metadata(object):
22
22
  Data from metadata file.
23
23
  geom : SimpleNamespace
24
24
  Geometry specific data.
25
- eperdn : float
26
- Electrons per dn conversion factor (detector k gain).
27
- fwc : float
28
- Full well capacity of detector.
29
- sat_thresh : float
30
- Multiplication factor for fwc that determines saturated cosmic pixels.
31
- plat_thresh : float
32
- Multiplication factor for fwc that determines edges of cosmic plateu.
33
- cosm_filter : int
34
- Minimum length in pixels of cosmic plateus to be identified.
35
- tail_filter : int
36
- Moving median filter window size for cosmic tail subtraction.
37
- cic_thresh : float
38
- Multiplication factor for readnoise that determines beginning of cic.
39
25
 
40
26
  B Nemati and S Miller - UAH - 03-Aug-2018
41
27
 
@@ -48,13 +34,6 @@ class Metadata(object):
48
34
  self.frame_rows = self.data['frame_rows']
49
35
  self.frame_cols = self.data['frame_cols']
50
36
  self.geom = self.data['geom']
51
- self.eperdn = self.data['eperdn']
52
- self.fwc = self.data['fwc']
53
- self.sat_thresh = self.data['sat_thresh']
54
- self.plat_thresh = self.data['plat_thresh']
55
- self.cosm_filter = self.data['cosm_filter']
56
- self.tail_filter = self.data['tail_filter']
57
- self.cic_thresh = self.data['cic_thresh']
58
37
 
59
38
  def get_data(self):
60
39
  """Read yaml data into dictionary."""
@@ -23,20 +23,6 @@ class MetadataWrapper(Metadata):
23
23
  Data from metadata file.
24
24
  geom : SimpleNamespace
25
25
  Geometry specific data.
26
- eperdn : float
27
- Electrons per dn conversion factor (detector k gain).
28
- fwc : float
29
- Full well capacity of detector.
30
- sat_thresh : float
31
- Multiplication factor for fwc that determines saturated cosmic pixels.
32
- plat_thresh : float
33
- Multiplication factor for fwc that determines edges of cosmic plateu.
34
- cosm_filter : int
35
- Minimum length in pixels of cosmic plateus to be identified.
36
- tail_filter : int
37
- Moving median filter window size for cosmic tail subtraction.
38
- cic_thresh : float
39
- Multiplication factor for readnoise that determines beginning of cic.
40
26
 
41
27
  """
42
28
 
@@ -0,0 +1,72 @@
1
+ Metadata-Version: 2.4
2
+ Name: emccd_detect
3
+ Version: 2.5.0
4
+ Summary: EMCCD detector image simulation
5
+ Author-email: Bijan Nemati <bijan.nemati@tellus1.com>, Sam Miller <sam.miller@uah.edu>, Kevin Ludwick <kevin.ludwick@uah.edu>
6
+ Classifier: Development Status :: 4 - Beta
7
+ Classifier: Intended Audience :: Developers
8
+ Classifier: Programming Language :: Python :: 3
9
+ Requires-Python: >=3.6
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE.txt
12
+ Requires-Dist: astropy
13
+ Requires-Dist: matplotlib
14
+ Requires-Dist: numpy
15
+ Requires-Dist: scipy
16
+ Requires-Dist: pynufft==2020.0.0
17
+ Requires-Dist: pyyaml
18
+ Dynamic: license-file
19
+
20
+ # EMCCD Detect
21
+
22
+ Given an input fluxmap, emccd_detect will return a simulated EMCCD detector image. Website: (<https://github.com/roman-corgi/emccd_detect/tree/master/emccd_detect>)
23
+
24
+
25
+ # Version
26
+
27
+ The latest version of emccd\_detect is 2.5.0. Main differences from previous version, 2.4.0:
28
+ --the ability to implement smear due to exposure of some rows while others are being read out. Credit for this smearing code: Peter Williams, Tellus1, 2024.
29
+ --the ability to implement non-uniformity in pixel response via an input master flat. Assumed to be a FITS file.
30
+
31
+
32
+ ## Getting Started
33
+ ### Installing
34
+
35
+ This package requires Python version 3.6 or higher. If the user wants the ability to apply charge transfer inefficiency (CTI) to detector frames using the optional tool (older version of arcticpy which is pure Python) provided in emccd\_detect, then the Python version should be >=3.6 and <=3.9. If the newer version of arcticpy (wrapper around C++ code) is installed, there is no upper limit restriction for Python version. For installation instructions and documentation for the newer arcticpy, see <https://github.com/jkeger/arctic>. emccd\_detect works apart from arcticpy and does not require it.
36
+
37
+ emccd\_detect is available on PyPI.org, so the following command will install the module (without CTI capabilities):
38
+
39
+ pip install emccd-detect
40
+
41
+ To install emccd\_detect instead from this package download, after downloading, navigate to the emccd\_detect directory where setup.py is located and use
42
+
43
+ pip install .
44
+
45
+ This will install emccd\_detect and its dependencies, which are as follows:
46
+
47
+ * astropy
48
+ * matplotlib
49
+ * numpy
50
+ * scipy
51
+ * pynufft==2020.0.0
52
+ * pyyaml
53
+
54
+ To optionally implement CTI capabilities with the pure-Python arcticpy, navigate to the arcticpy directory (<https://github.com/roman-corgi/emccd_detect/tree/master/arcticpy_folder>), and there will be a file called setup.py in that directory. Use
55
+
56
+ pip install .
57
+
58
+ This will install arcticpy version 1.0. See (<https://github.com/jkeger/arcticpy/tree/row_wise/arcticpy>) for documentation. If
59
+ you have Python>3.9, the CTI functionality will not work if you are using the arcticpy installation that was included with this emccd_detect package, but everything else will work fine.
60
+
61
+
62
+ ### Usage
63
+
64
+ For an example of how to use emccd\_detect, see example_script.py.
65
+
66
+
67
+ ## Authors
68
+
69
+ * Bijan Nemati (<bijan.nemati@tellus1.com>)
70
+ * Sam Miller (<sam.miller@uah.edu>)
71
+ * Kevin Ludwick (<kevin.ludwick@uah.edu>)
72
+
@@ -0,0 +1,14 @@
1
+ emccd_detect/__init__.py,sha256=uWZwY5HGOMhZbYvLBHUIJ1__9KWeLAx2rdkOL0oplTg,45
2
+ emccd_detect/cosmics.py,sha256=wRE47QOB3fwxkH5PHTeoyLjJ0fgJki6Z8hLDPx2h3SQ,3991
3
+ emccd_detect/emccd_detect.py,sha256=tjNLAZP4N2WlU3jluD1tww4CmM3T1gxw46aL3cw_CR0,30223
4
+ emccd_detect/nonlinearity.py,sha256=DWBGjoShInMXBX0BLj6lT9dlY_lx6pdn8VU84jk_djU,4938
5
+ emccd_detect/rand_em_gain.py,sha256=3eF9T7PNYFZT0coGZwBmNTYz6B9pj2lXxTR8ROG6_7Q,6297
6
+ emccd_detect/util/__init__.py,sha256=iwhKnzeBJLKxpRVjvzwiRE63_zNpIBfaKLITauVph-0,24
7
+ emccd_detect/util/metadata.yaml,sha256=G0-Uy3wA7tmPXcoFS3ZD1iomIw4hvSRl58RGJjIJeLM,1034
8
+ emccd_detect/util/read_metadata.py,sha256=YgqdGJrWCqO0VUJ9gTrUYxK0wjI8NyqEwyodIgllDAE,1805
9
+ emccd_detect/util/read_metadata_wrapper.py,sha256=Em22IK3s9ZL-4H-g7yvJVlhdYd4Vez_MLflPdnJldJg,4848
10
+ emccd_detect-2.5.0.dist-info/licenses/LICENSE.txt,sha256=k8FrCPoTUgsCsv9PNH_OLV9tcPdnAlUeU_YQOSJLcfc,1100
11
+ emccd_detect-2.5.0.dist-info/METADATA,sha256=mbhbsf05RUYmLvOLpkZaZ8Q9Sn3K5k7PZeG7rAUCzfo,3082
12
+ emccd_detect-2.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
+ emccd_detect-2.5.0.dist-info/top_level.txt,sha256=V0qxOcGf8TowSJXnTxWEMuK9BBsySwhtKNitfdokD0A,13
14
+ emccd_detect-2.5.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (74.1.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Bijan Nemati, Sam Miller, and Kevin Ludwick
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,69 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: emccd_detect
3
- Version: 2.3.0
4
- Summary: EMCCD detector image simulation
5
- Home-page: https://github.jpl.nasa.gov/WFIRST-CGI/emccd_detect
6
- Author: Bijan Nemati, Sam Miller, Kevin Ludwick
7
- Author-email: bijan.nemati@tellus1.com, sam.miller@uah.edu, kevin.ludwick@uah.edu
8
- Classifier: Development Status :: 4 - Beta
9
- Classifier: Intended Audience :: Developers
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.6
12
- Classifier: Programming Language :: Python :: 3.7
13
- Classifier: Programming Language :: Python :: 3.8
14
- Requires-Python: >=3.6
15
- Description-Content-Type: text/markdown
16
- Requires-Dist: astropy
17
- Requires-Dist: matplotlib
18
- Requires-Dist: numpy
19
- Requires-Dist: scipy
20
- Requires-Dist: pynufft ==2020.0.0
21
- Requires-Dist: pyyaml
22
-
23
- # EMCCD Detect
24
-
25
- Given an input fluxmap, emccd_detect will return a simulated EMCCD detector image. Website: (<https://github.com/roman-corgi/emccd_detect/tree/master/emccd_detect>)
26
-
27
-
28
- # Version
29
-
30
- The latest version of emccd\_detect is 2.3.0.
31
-
32
-
33
- ## Getting Started
34
- ### Installing
35
-
36
- This package requires Python version 3.6 or higher. If the user wants the ability to apply charge transfer inefficiency (CTI) to detector frames using the optional tool provided in emccd\_detect, then the Python version should be >=3.6 and <=3.9.
37
-
38
- To install emccd\_detect, navigate to the emccd\_detect directory where setup.py is located and use
39
-
40
- pip install .
41
-
42
- This will install emccd\_detect and its dependencies, which are as follows:
43
-
44
- * astropy
45
- * matplotlib
46
- * numpy
47
- * scipy
48
- * pynufft==2020.0.0
49
- * pyyaml
50
-
51
- To optionally implement CTI capabilities, navigate to the arcticpy directory (<https://github.com/roman-corgi/emccd_detect/tree/master/arcticpy_folder>), and there will be a file called setup.py in that directory. Use
52
-
53
- pip install .
54
-
55
- This will install arcticpy version 1.0, which is an older version of arcticpy which runs purely on Python (<https://github.com/jkeger/arcticpy/tree/row_wise/arcticpy>). If
56
- you have Python>=3.10, the CTI functionality will not work if you are using the arcticpy installation that was included with this emccd_detect package, but everything else will work fine.
57
-
58
-
59
- ### Usage
60
-
61
- For an example of how to use emccd\_detect, see example_script.py.
62
-
63
-
64
- ## Authors
65
-
66
- * Bijan Nemati (<bijan.nemati@tellus1.com>)
67
- * Sam Miller (<sam.miller@uah.edu>)
68
- * Kevin Ludwick (<kevin.ludwick@uah.edu>)
69
-
@@ -1,13 +0,0 @@
1
- emccd_detect/__init__.py,sha256=p-NmfUlr25lTkWkeCxbgt34N36FhFb8AqPQG7WvWx8E,45
2
- emccd_detect/cosmics.py,sha256=wRE47QOB3fwxkH5PHTeoyLjJ0fgJki6Z8hLDPx2h3SQ,3991
3
- emccd_detect/emccd_detect.py,sha256=Ige6TKmeR4xHW2Jd_XOnG-NMHNodS_nr1dgGv0x6B_k,23136
4
- emccd_detect/nonlinearity.py,sha256=sWsYXbH5Ck2DSUntC0zbXlmsTzYw73T27tIKs41nApQ,4822
5
- emccd_detect/rand_em_gain.py,sha256=3eF9T7PNYFZT0coGZwBmNTYz6B9pj2lXxTR8ROG6_7Q,6297
6
- emccd_detect/util/__init__.py,sha256=iwhKnzeBJLKxpRVjvzwiRE63_zNpIBfaKLITauVph-0,24
7
- emccd_detect/util/metadata.yaml,sha256=hcKTg4kMy12dfbCmmvZeKEqjeUA3BYiAcZc5vZpc3bE,1149
8
- emccd_detect/util/read_metadata.py,sha256=r511ENJ6zbIvLDWiVic7KsVXYrBphSdTKUQbuwocjLs,2764
9
- emccd_detect/util/read_metadata_wrapper.py,sha256=oBh2KpJ-uLTSIY_hPzw8sNIcJ6MENBSf38ks8OaFOSQ,5473
10
- emccd_detect-2.3.0.dist-info/METADATA,sha256=VDjFt5KKwFd8sM1XnF9M2DStCHWIkQ54zq6ia4P-0E8,2391
11
- emccd_detect-2.3.0.dist-info/WHEEL,sha256=uCRv0ZEik_232NlR4YDw4Pv3Ajt5bKvMH13NUU7hFuI,91
12
- emccd_detect-2.3.0.dist-info/top_level.txt,sha256=V0qxOcGf8TowSJXnTxWEMuK9BBsySwhtKNitfdokD0A,13
13
- emccd_detect-2.3.0.dist-info/RECORD,,