Commit ce65a752aa935493f897ffe165c4929ecf15ae5f
1 parent
127eb18e
Exists in
master
Update the Filename class.
Showing
6 changed files
with
600 additions
and
178 deletions
Show diff stats
docs/source/index.rst
... | ... | @@ -30,8 +30,8 @@ The source code of Guitastro is available using `Git <https://git-scm.com/>`_. |
30 | 30 | Windows users can install `Tortoige Git <https://tortoisegit.org/>`_ which is user friendly. |
31 | 31 | |
32 | 32 | You can get Guitastro anywhere in your computer. The examples of this guide consider |
33 | -to place Guitastro in the folder Documents of your user. Of the user is xxx | |
34 | -for linux will install guitastro in the folder /home/xxx/Documents. For | |
33 | +to place Guitastro in the folder Documents of your user. If the user is xxx | |
34 | +for linux you have to install guitastro in the folder /home/xxx/Documents. For | |
35 | 35 | Windows users it corresponds to C:\\Users\\xxx\\Documents |
36 | 36 | |
37 | 37 | Clone the code from the Git repository `https://gitlab.irap.omp.eu/guitastrolib/guitastro.git <https://gitlab.irap.omp.eu/guitastrolib/guitastro.git>`_. | ... | ... |
src/guitastro/__init__.py
... | ... | @@ -49,6 +49,21 @@ guitastro.targets |
49 | 49 | .. automodule:: guitastro.targets |
50 | 50 | :members: |
51 | 51 | |
52 | +guitastro.ephemeris | |
53 | +------------------- | |
54 | +.. automodule:: guitastro.ephemeris | |
55 | + :members: | |
56 | + | |
57 | +guitastro.filenames | |
58 | +------------------- | |
59 | +.. automodule:: guitastro.filenames | |
60 | + :members: | |
61 | + | |
62 | +guitastro.astrotables | |
63 | +--------------------- | |
64 | +.. automodule:: guitastro.astrotables | |
65 | + :members: | |
66 | + | |
52 | 67 | guitastro.camera |
53 | 68 | ----------------- |
54 | 69 | .. automodule:: guitastro.camera |
... | ... | @@ -74,10 +89,6 @@ guitastro.etc |
74 | 89 | .. automodule:: guitastro.etc |
75 | 90 | :members: |
76 | 91 | |
77 | -guitastro.ephemeris | |
78 | -------------------- | |
79 | -.. automodule:: guitastro.ephemeris | |
80 | - :members: | |
81 | 92 | |
82 | 93 | guitastro.visu |
83 | 94 | -------------- |
... | ... | @@ -99,16 +110,6 @@ guitastro.voevent |
99 | 110 | .. automodule:: guitastro.voevent |
100 | 111 | :members: |
101 | 112 | |
102 | -guitastro.filenames | |
103 | -------------------- | |
104 | -.. automodule:: guitastro.filenames | |
105 | - :members: | |
106 | - | |
107 | -guitastro.astrotables | |
108 | ---------------------- | |
109 | -.. automodule:: guitastro.astrotables | |
110 | - :members: | |
111 | - | |
112 | 113 | guitastro.splinefit |
113 | 114 | ------------------- |
114 | 115 | .. automodule:: guitastro.splinefit | ... | ... |
src/guitastro/filenames.py
... | ... | @@ -20,6 +20,7 @@ client.notify_all(message) |
20 | 20 | import os, glob, sys |
21 | 21 | import datetime |
22 | 22 | import math |
23 | +#import inspect | |
23 | 24 | |
24 | 25 | import tkinter as tk |
25 | 26 | from tkinter.filedialog import askopenfilename, asksaveasfilename |
... | ... | @@ -107,6 +108,7 @@ class Filenames(FilenamesException, GuitastroTools): |
107 | 108 | self._verbose_level = self.VERBOSE_NONE |
108 | 109 | self._longiau_deg = 0.0 |
109 | 110 | self._naming = self.NAMING_NONE |
111 | + self._outfilename = os.path.join(self._image_dir, "noname"+self.extension()) | |
110 | 112 | |
111 | 113 | def __repr__(self): |
112 | 114 | return str(self) |
... | ... | @@ -118,6 +120,8 @@ class Filenames(FilenamesException, GuitastroTools): |
118 | 120 | def longitude(self, longiau_deg:float): |
119 | 121 | """ Set the longitude of the observation siteobs. |
120 | 122 | |
123 | + This method is useful for the method get_night(). | |
124 | + | |
121 | 125 | Args: |
122 | 126 | longiau_deg: The longitude of the siteobs must expressed in degrees, east increasing, from 0 to 360 (IAU convention). |
123 | 127 | |
... | ... | @@ -213,22 +217,58 @@ class Filenames(FilenamesException, GuitastroTools): |
213 | 217 | print(fn.naming_rules()) |
214 | 218 | |
215 | 219 | """ |
220 | + date_iso = datetime.datetime.utcnow().isoformat() | |
221 | + name = self._naming_list[self._naming] | |
216 | 222 | texte = "" |
217 | - texte +=f"Naming rules for {self._naming_list[self._naming]}\n\n" | |
218 | 223 | if self._naming == self.NAMING_NONE: |
219 | - texte += "No specific rule.\n" | |
224 | + texte += "Filename naming rules\n" | |
225 | + else: | |
226 | + texte +=f"Filename naming rules for {name}\n" | |
227 | + date_iso = datetime.datetime.utcnow().isoformat() | |
228 | + texte += "Updated on 2022-11-19T12:48:00\n" | |
229 | + texte +=f"Written on {date_iso}\n" | |
230 | + # --- | |
231 | + h1 = "1. Introduction" | |
232 | + texte +=f"\n{h1}\n" + "="*len(h1) + "\n\n" | |
233 | + if self._naming == self.NAMING_NONE: | |
234 | + texte += "No specific rule. File names can be formed as you want.\n" | |
235 | + return texte | |
236 | + elif self._naming == self.NAMING_PYROS1: | |
237 | + texte +=f"{name} is a file name format for the Python Robotic Observatory Software.\n" | |
238 | + texte += "Specific terminology:\n" | |
239 | + texte += "* Unit: The set of Mount and Channels that define a 'telescope'.\n" | |
240 | + texte += "* Channel: An optical path + camera of a Unit. A unit can have many Channels.\n" | |
241 | + texte += "* Album: A set of Channels for which data can be combined by post processing.\n" | |
242 | + texte += "* Sequence: A set of Albums. A sequence is a hierarchy Channels/Planes/Frames.\n" | |
243 | + texte += "* Plane: A set of Frames. A Plane is composed by Frames.\n" | |
244 | + texte += "* Frame: A unitary record (e.g. an image).\n" | |
245 | + # --- | |
246 | + h1 = "2. Format of the file names" | |
247 | + texte +=f"\n{h1}\n" + "="*len(h1) + "\n\n" | |
220 | 248 | if self._naming == self.NAMING_PYROS1: |
221 | - texte +=" 1 2 3 4\n" | |
222 | - texte += "0123456789 123456789 123456789 123456789 12345\n" | |
223 | - texte += "TT_YYYYMMDD_hhmmsscccccc_UUU_V_CCC_IIIIIIIIII\n" | |
249 | + texte += " 1 2 3 4 5\n" | |
250 | + texte += "0123456789 123456789 123456789 123456789 123456789 12\n" | |
251 | + texte += "TT_YYYYMMDD_hhmmsscccccc_V_UUU_CCC_IIIIIIIIII_PPP_FFF\n" | |
224 | 252 | texte += "\n" |
225 | 253 | texte +=f"TT = 'ftype' = file type amongst {self._naming_0_stypes}\n" |
226 | 254 | texte += "YYYYMMDD = 'date' = Year Month Day. e.g. 20221109\n" |
227 | 255 | texte += "hhmmsscccccc = 'time' = Hours Minutes Seconds Microseconds. e.g. 235604123456\n" |
228 | - texte += "UUU = 'unit' = Telescope unit. e.g. TNC\n" | |
229 | 256 | texte += "V = 'version' = Version of the naming rule. e.g. 1\n" |
257 | + texte += "UUU = 'unit' = Telescope unit. e.g. TNC\n" | |
230 | 258 | texte += "CCC = 'channel' = Optical channel designation. e.g. CH1\n" |
231 | 259 | texte += "IIIIIIIIII = 'id_seq' = ID of the file in the database. e.g. 0000001234\n" |
260 | + texte += "PPP = 'plane' = index of the plane. e.g. 001\n" | |
261 | + texte += "FFF = 'frame' = index of the frame. e.g. 012\n" | |
262 | + # --- | |
263 | + h1 = "3. Remarks" | |
264 | + texte +=f"\n{h1}\n" + "="*len(h1) + "\n\n" | |
265 | + if self._naming == self.NAMING_PYROS1: | |
266 | + texte += "Example: L0_20221109_235406123456_1_TNC_CH1_0123456789_001_001\n" | |
267 | + texte += "UUU, CCC are accronyms (string)\n" | |
268 | + texte += "V, IIIIIIIIII, PPP, FFF are digits (int)\n" | |
269 | + texte += "CCC is a Channel for L0,L1 ftype levels but should by the Album for L2 level" | |
270 | + # --- | |
271 | + texte += "\n\n=== End of the Document ===" | |
232 | 272 | return texte |
233 | 273 | |
234 | 274 | def naming_ident(self, fname:str) -> dict: |
... | ... | @@ -245,22 +285,24 @@ class Filenames(FilenamesException, GuitastroTools): |
245 | 285 | :: |
246 | 286 | |
247 | 287 | fn = Filenames() |
248 | - fn.naming_ident("L0_20221109_235406123456_TNC_1_CH1_0123456789") | |
288 | + fn.naming_ident("L0_20221109_235406123456_1_TNC_CH1_0123456789_001_001") | |
249 | 289 | >>> 'PyROS.1' |
250 | 290 | """ |
251 | 291 | naming = self.NAMING_NONE |
252 | 292 | n = len(fname) |
253 | - if n == 45: | |
293 | + if n == 53: | |
254 | 294 | words = fname.split("_") |
255 | 295 | n = len(words) |
256 | - if n == 7: | |
296 | + if n == 9: | |
257 | 297 | param['ftype'] = words[0] |
258 | 298 | param['date'] = words[1] |
259 | 299 | param['time'] = words[2] |
260 | - param['unit'] = words[3] | |
261 | - param['version'] = words[4] | |
300 | + param['version'] = words[3] | |
301 | + param['unit'] = words[4] | |
262 | 302 | param['channel'] = words[5] |
263 | 303 | param['id_seq'] = words[6] |
304 | + param['plane'] = words[7] | |
305 | + param['frame'] = words[8] | |
264 | 306 | try: |
265 | 307 | fname_verified = self.naming_set(**param) |
266 | 308 | if fname == fname_verified: |
... | ... | @@ -284,9 +326,9 @@ class Filenames(FilenamesException, GuitastroTools): |
284 | 326 | |
285 | 327 | fn = Filenames() |
286 | 328 | fn.naming("PyROS.1") |
287 | - params = fn.naming_get("L0_20221109_235406123456_TNC_1_CH1_0123456789") | |
329 | + params = fn.naming_get("L0_20221109_235406123456_1_TNC_CH1_0123456789_001_012") | |
288 | 330 | |
289 | - The answer (params dict) should be {'ftype': 'L0', 'date': '20221109', 'time': '235406123456', 'unit': 'TNC', 'version': '1', 'channel': 'CH1', 'id_seq': '0123456789'} | |
331 | + The answer (params dict) should be {'ftype': 'L0', 'date': '20221109', 'time': '235406123456', 'version': '1', 'unit': 'TNC', 'channel': 'CH1', 'id_seq': '0123456789', 'plane': '001', 'frame': '012'} | |
290 | 332 | """ |
291 | 333 | param = {} |
292 | 334 | see_rules = self._see_rules |
... | ... | @@ -294,21 +336,25 @@ class Filenames(FilenamesException, GuitastroTools): |
294 | 336 | param['fname'] = fname |
295 | 337 | elif self._naming == self.NAMING_PYROS1: |
296 | 338 | n = len(fname) |
297 | - if n != 45: | |
298 | - texte = "File name must be a string of 45 characters" + see_rules | |
339 | + nn = 53 | |
340 | + if n != nn: | |
341 | + texte =f"File name must be a string of {nn} characters" + see_rules | |
299 | 342 | raise FilenamesException(FilenamesException.BAD_FILENAME_RULE, texte) |
300 | 343 | words = fname.split("_") |
301 | 344 | n = len(words) |
302 | - if n != 7: | |
303 | - texte = "File name must contain 6 underscore characters" + see_rules | |
345 | + nn = 9 | |
346 | + if n != nn: | |
347 | + texte =f"File name must contain {nn-1} underscore characters" + see_rules | |
304 | 348 | raise FilenamesException(FilenamesException.BAD_FILENAME_RULE, texte) |
305 | 349 | param['ftype'] = words[0] |
306 | 350 | param['date'] = words[1] |
307 | 351 | param['time'] = words[2] |
308 | - param['unit'] = words[3] | |
309 | - param['version'] = words[4] | |
352 | + param['version'] = words[3] | |
353 | + param['unit'] = words[4] | |
310 | 354 | param['channel'] = words[5] |
311 | 355 | param['id_seq'] = words[6] |
356 | + param['plane'] = words[7] | |
357 | + param['frame'] = words[8] | |
312 | 358 | fname_verified = self.naming_set(**param) |
313 | 359 | if fname != fname_verified: |
314 | 360 | raise FilenamesException(FilenamesException.BAD_FILENAME_RULE) |
... | ... | @@ -334,13 +380,16 @@ class Filenames(FilenamesException, GuitastroTools): |
334 | 380 | param['ftype'] = "L0" |
335 | 381 | param['date'] = "20221109" |
336 | 382 | param['time'] = "235406123456" |
337 | - param['unit'] = "TNC" | |
338 | 383 | param['version'] = "1" |
384 | + param['unit'] = "TNC" | |
339 | 385 | param['channel'] = "CH1" |
340 | 386 | param['id_seq'] = "0123456789" |
387 | + param['plane'] = "001" | |
388 | + param['frame'] = "001" | |
341 | 389 | fname = fn.naming_set(**param) |
342 | 390 | |
343 | - The answer should be L0_20221109_235406123456_TNC_1_CH1_0123456789. | |
391 | + The answer should be L0_20221109_235406123456_TNC_1_CH1_0123456789_001_001. | |
392 | + If param['date'] is "*" then the date and time will be the current UTC time. | |
344 | 393 | """ |
345 | 394 | see_rules = self._see_rules |
346 | 395 | if self._naming == self.NAMING_NONE: |
... | ... | @@ -353,10 +402,12 @@ class Filenames(FilenamesException, GuitastroTools): |
353 | 402 | param['ftype'] = "" |
354 | 403 | param['date'] = "" |
355 | 404 | param['time'] = "" |
356 | - param['unit'] = "" | |
357 | 405 | param['version'] = "" |
406 | + param['unit'] = "" | |
358 | 407 | param['channel'] = "" |
359 | 408 | param['id_seq'] = "" |
409 | + param['plane'] = "" | |
410 | + param['frame'] = "" | |
360 | 411 | for key, val in kwargs.items(): |
361 | 412 | if key in param.keys(): |
362 | 413 | param[key] = val |
... | ... | @@ -376,6 +427,13 @@ class Filenames(FilenamesException, GuitastroTools): |
376 | 427 | if len(param['date']) == 8: |
377 | 428 | if param['date'].isdigit(): |
378 | 429 | valid = True |
430 | + elif param['date'] == "*": | |
431 | + d = datetime.datetime.utcnow().isoformat() | |
432 | + fdate = d[0:4]+d[5:7]+d[8:10] | |
433 | + ftime = d[11:13]+d[14:16]+d[17:19]+d[20:26] | |
434 | + param['date'] = fdate | |
435 | + param['time'] = ftime | |
436 | + valid = True | |
379 | 437 | if valid == False: |
380 | 438 | texte = f"Date {param['date']} must be a string of 8 digits" + see_rules |
381 | 439 | raise FilenamesException(FilenamesException.BAD_PARAM, texte) |
... | ... | @@ -388,24 +446,27 @@ class Filenames(FilenamesException, GuitastroTools): |
388 | 446 | if valid == False: |
389 | 447 | texte = f"Date {param['time']} must be a string of 12 digits" + see_rules |
390 | 448 | raise FilenamesException(FilenamesException.BAD_PARAM, texte) |
391 | - # --- verify unit | |
392 | - valid = False | |
393 | - if isinstance(param['unit'],str): | |
394 | - if len(param['unit']) == 3: | |
395 | - valid = True | |
396 | - if valid == False: | |
397 | - texte = f"Unit {param['unit']} must be a string of 3 characters" + see_rules | |
398 | - raise FilenamesException(FilenamesException.BAD_PARAM, texte) | |
399 | 449 | # --- verify version |
400 | 450 | valid = False |
401 | 451 | if isinstance(param['version'],str): |
402 | 452 | if len(param['version']) == 1: |
403 | 453 | valid = True |
454 | + elif isinstance(param['version'],int): | |
455 | + param['version'] = f"{param['version']:01d}" | |
456 | + valid = True | |
404 | 457 | if valid == False: |
405 | 458 | texte = f"Version {param['version']} must be a string of 1 character" + see_rules |
406 | 459 | raise FilenamesException(FilenamesException.BAD_PARAM, texte) |
407 | 460 | # --- verify unit |
408 | 461 | valid = False |
462 | + if isinstance(param['unit'],str): | |
463 | + if len(param['unit']) == 3: | |
464 | + valid = True | |
465 | + if valid == False: | |
466 | + texte = f"Unit {param['unit']} must be a string of 3 characters" + see_rules | |
467 | + raise FilenamesException(FilenamesException.BAD_PARAM, texte) | |
468 | + # --- verify channel | |
469 | + valid = False | |
409 | 470 | if isinstance(param['channel'],str): |
410 | 471 | if len(param['channel']) == 3: |
411 | 472 | valid = True |
... | ... | @@ -417,13 +478,36 @@ class Filenames(FilenamesException, GuitastroTools): |
417 | 478 | if isinstance(param['id_seq'],str): |
418 | 479 | if len(param['id_seq']) == 10: |
419 | 480 | valid = True |
420 | - elif isinstance(param['id_seq'],type(int)): | |
481 | + elif isinstance(param['id_seq'],int): | |
421 | 482 | param['id_seq'] = f"{param['id_seq']:010d}" |
422 | 483 | valid = True |
423 | 484 | if valid == False: |
424 | 485 | texte = f"Id_seq {param['id_seq']} must be a string of 10 characters or an integer" + see_rules |
425 | 486 | raise FilenamesException(FilenamesException.BAD_PARAM, texte) |
426 | - fname = param['ftype']+"_"+param['date']+"_"+param['time']+"_"+param['unit']+"_"+param['version']+"_"+param['channel']+"_"+param['id_seq'] | |
487 | + # --- verify plane | |
488 | + valid = False | |
489 | + if isinstance(param['plane'],str): | |
490 | + if len(param['plane']) == 3: | |
491 | + valid = True | |
492 | + elif isinstance(param['plane'],int): | |
493 | + param['plane'] = f"{param['plane']:03d}" | |
494 | + valid = True | |
495 | + if valid == False: | |
496 | + texte = f"Plane {param['plane']} must be a string of 3 characters or an integer" + see_rules | |
497 | + raise FilenamesException(FilenamesException.BAD_PARAM, texte) | |
498 | + # --- verify frame | |
499 | + valid = False | |
500 | + if isinstance(param['frame'],str): | |
501 | + if len(param['frame']) == 3: | |
502 | + valid = True | |
503 | + elif isinstance(param['frame'],int): | |
504 | + param['frame'] = f"{param['frame']:03d}" | |
505 | + valid = True | |
506 | + if valid == False: | |
507 | + texte = f"Frame {param['frame']} must be a string of 3 characters or an integer" + see_rules | |
508 | + raise FilenamesException(FilenamesException.BAD_PARAM, texte) | |
509 | + # --- form final file name | |
510 | + fname = param['ftype']+"_"+param['date']+"_"+param['time']+"_"+param['version']+"_"+param['unit']+"_"+param['channel']+"_"+param['id_seq']+"_"+param['plane']+"_"+param['frame'] | |
427 | 511 | return fname |
428 | 512 | |
429 | 513 | |
... | ... | @@ -448,13 +532,13 @@ class Filenames(FilenamesException, GuitastroTools): |
448 | 532 | return self._image_dir |
449 | 533 | |
450 | 534 | def extension(self, extension: str="") -> str: |
451 | - """Set/Get the extension of the FITS files. | |
535 | + """Set/Get the extension of the files. | |
452 | 536 | |
453 | 537 | Args: |
454 | - extension: Set the file extension to add automatically to FITS files saved with method save. Defaut value is ".fit". | |
538 | + extension: Set the file extension to (usefull add automatically to files when record). Defaut value is ".fit". | |
455 | 539 | |
456 | 540 | Returns: |
457 | - The current extension added to FITS files. | |
541 | + The current extension added to files. | |
458 | 542 | |
459 | 543 | """ |
460 | 544 | if extension != "": |
... | ... | @@ -466,7 +550,7 @@ class Filenames(FilenamesException, GuitastroTools): |
466 | 550 | def get_night(self, date: str="now")->str: |
467 | 551 | """Get the current night identifier as a string of 8 characters: YYYYMMDD. |
468 | 552 | |
469 | - The night identifier changes at local noon. So it used the longitude of the siteobs. | |
553 | + The night identifier changes at local noon. So it uses the longitude defined in longitude() method. | |
470 | 554 | |
471 | 555 | Args: |
472 | 556 | date: Input date to compute the night identifier. Defaut value is "now". |
... | ... | @@ -476,9 +560,9 @@ class Filenames(FilenamesException, GuitastroTools): |
476 | 560 | |
477 | 561 | :: |
478 | 562 | |
479 | - ima1 = Ima() | |
480 | - ima1.longitude = 2.3456 | |
481 | - night = ima1.get_night("now") | |
563 | + fn = Filenames() | |
564 | + fn.longitude = 2.3456 | |
565 | + night = fn.get_night("now") | |
482 | 566 | |
483 | 567 | The variable night contains the current night in the format YYYYMMDD. |
484 | 568 | """ |
... | ... | @@ -516,8 +600,8 @@ class Filenames(FilenamesException, GuitastroTools): |
516 | 600 | |
517 | 601 | :: |
518 | 602 | |
519 | - ima1 = Ima() | |
520 | - fullname = ima1.fullfilename("m57") | |
603 | + fn = Filenames() | |
604 | + fullname = fn.fullfilename("m57") | |
521 | 605 | |
522 | 606 | The result could be '/srv/develop/guitastro/test/data/m57.fit' |
523 | 607 | |
... | ... | @@ -546,8 +630,8 @@ class Filenames(FilenamesException, GuitastroTools): |
546 | 630 | |
547 | 631 | :: |
548 | 632 | |
549 | - ima1 = Ima() | |
550 | - fullname = ima1.basename("m57") | |
633 | + fn = Filenames() | |
634 | + fullname = fn.basename("m57") | |
551 | 635 | |
552 | 636 | The result could be 'm57.fit' |
553 | 637 | |
... | ... | @@ -558,11 +642,18 @@ class Filenames(FilenamesException, GuitastroTools): |
558 | 642 | basename = os.path.basename(fitsname) |
559 | 643 | return basename |
560 | 644 | |
561 | - def itername(self, fitsname:str): | |
562 | - """Get an iterator according a series of FITS files. | |
645 | + def itername(self, fitsname:str, **kwargs): | |
646 | + """Get an iterator according a series of files. | |
647 | + | |
648 | + The list of file names is generated internally by the method genename(). | |
563 | 649 | |
564 | 650 | Args: |
565 | 651 | fitsname: Input file name of a series with or without path or extension. |
652 | + **kwargs: a dictionnary of optional parameters: | |
653 | + | |
654 | + * 'first': Lower index to keep indexes. | |
655 | + * 'last': Upper index to keep indexes. | |
656 | + * 'indexes': List of indexes to keep (integers). | |
566 | 657 | |
567 | 658 | Returns: |
568 | 659 | The iterator of the series of files. |
... | ... | @@ -572,7 +663,8 @@ class Filenames(FilenamesException, GuitastroTools): |
572 | 663 | |
573 | 664 | :: |
574 | 665 | |
575 | - for fitsname in ima1.itername("m63-1"): | |
666 | + fn = Filenames() | |
667 | + for fitsname in fn.itername("m63-1"): | |
576 | 668 | print(f"fitsname={fitsname}") |
577 | 669 | |
578 | 670 | """ |
... | ... | @@ -587,11 +679,18 @@ class Filenames(FilenamesException, GuitastroTools): |
587 | 679 | fitsname = os.path.join(dirname, genename + sep + index + suffix + file_extension) |
588 | 680 | yield fitsname |
589 | 681 | |
590 | - def enumname(self, fitsname: str): | |
591 | - """Get an enumerator according a series of FITS files. | |
682 | + def enumname(self, fitsname: str, **kwargs): | |
683 | + """Get an enumerator according a series of files. | |
684 | + | |
685 | + The list of file names is generated internally by the method genename(). | |
592 | 686 | |
593 | 687 | Args: |
594 | 688 | fitsname: Input file name of a series with or without path or extension. |
689 | + **kwargs: a dictionnary of optional parameters: | |
690 | + | |
691 | + * 'first': Lower index to keep indexes. | |
692 | + * 'last': Upper index to keep indexes. | |
693 | + * 'indexes': List of indexes to keep (integers). | |
595 | 694 | |
596 | 695 | Returns: |
597 | 696 | The iterator of the series of files. |
... | ... | @@ -601,11 +700,12 @@ class Filenames(FilenamesException, GuitastroTools): |
601 | 700 | |
602 | 701 | :: |
603 | 702 | |
604 | - for k, fitsname in enumarate(ima1.enumname("m63-1")): | |
703 | + fn = Filenames() | |
704 | + for k, fitsname in enumarate(fn.enumname("m63-1")): | |
605 | 705 | print(f"fitsname {k} = {fitsname}") |
606 | 706 | |
607 | 707 | """ |
608 | - dico = self.genename(fitsname) | |
708 | + dico = self.genename(fitsname, **kwargs) | |
609 | 709 | dirname = dico['dirname'] |
610 | 710 | genename = dico['genename'] |
611 | 711 | sep = dico['sep'] |
... | ... | @@ -631,35 +731,70 @@ class Filenames(FilenamesException, GuitastroTools): |
631 | 731 | return filename, file_extension |
632 | 732 | |
633 | 733 | def genenames(self, wildcard: str)-> dict: |
734 | + """Generate a dictionnary describing a series of files associated to a wildcard file name. | |
735 | + | |
736 | + Generated file names are existing in the disk. | |
737 | + This method is similar as genename() but the input file is a wildcard and the output dictionary is different. | |
738 | + | |
739 | + Args: | |
740 | + wildcard: Any wildcard with extension. The path is that defined in the method path() is not in the wildcard. | |
741 | + | |
742 | + Returns: | |
743 | + A dictionary containing the following keys: | |
744 | + | |
745 | + * 'dirname': Directory name (path only) | |
746 | + * 'shortname': Short name (no path, extension) | |
747 | + * 'filename': Full name of file (no path, shortname, no extension) | |
748 | + * 'ext': Extension of the file | |
749 | + | |
750 | + For example, you have 3 files m63-1.fit, m63-2.fit and m63-3.fit. | |
751 | + You have to put one of the three file names as input of the method genename: | |
752 | + | |
753 | + :: | |
754 | + | |
755 | + fn = Filenames() | |
756 | + result = fn.genenames("m63-*.fits") | |
757 | + | |
758 | + """ | |
634 | 759 | # fn.genenames("IM_*.fits.gz") |
635 | 760 | wildcard = self.fullfilename(wildcard) |
636 | - print(f"wildcard = {wildcard}") | |
761 | + #print(f"wildcard = {wildcard}") | |
637 | 762 | ftmps = glob.glob(wildcard) |
638 | 763 | allshortnames = [] |
639 | 764 | for ftmp in ftmps: |
640 | 765 | basename = os.path.basename(ftmp) |
766 | + dirname = os.path.dirname(ftmp) | |
641 | 767 | allshortnames.append(basename) |
642 | 768 | # --- |
643 | 769 | allshorts = [] |
644 | 770 | for shortname in allshortnames: |
645 | 771 | dico = {} |
646 | - nchar = len(shortname) | |
772 | + #nchar = len(shortname) | |
647 | 773 | filename , file_extension = self._split_extension(shortname) |
774 | + dico['dirname'] = dirname | |
648 | 775 | dico['shortname'] = shortname |
649 | 776 | dico['filename'] = filename |
650 | 777 | dico['ext'] = file_extension |
651 | - for shortname_ref in allshortnames: | |
652 | - nchar_ref = len(shortname_ref) | |
778 | + #for shortname_ref in allshortnames: | |
779 | + # nchar_ref = len(shortname_ref) | |
653 | 780 | allshorts.append(dico) |
654 | 781 | |
655 | 782 | return allshorts |
656 | 783 | |
657 | - def genename(self,fitsname: str)-> dict: | |
658 | - """ | |
659 | - Generate a dictionnary describing a series of files associated to a FITS file name. | |
784 | + def genename(self,fitsname: str, **kwargs)-> dict: | |
785 | + """Generate a dictionnary describing a series of files associated to a file name. | |
786 | + | |
787 | + The algorithm search for files having indexes with a name similar than fitsname. | |
788 | + Generated file names are existing in the disk. | |
789 | + This method adds the possibility to restrict indexes using options 'first', 'last' and 'indexes' (using optional parameters). | |
660 | 790 | |
661 | 791 | Args: |
662 | 792 | fitsname: Any file name with or without path or extension. |
793 | + **kwargs: a dictionnary of optional parameters: | |
794 | + | |
795 | + * 'first': Lower index to keep indexes. | |
796 | + * 'last': Upper index to keep indexes. | |
797 | + * 'indexes': List of indexes to keep (integers). | |
663 | 798 | |
664 | 799 | Returns: |
665 | 800 | A dictionary containing the following keys: |
... | ... | @@ -676,8 +811,21 @@ class Filenames(FilenamesException, GuitastroTools): |
676 | 811 | |
677 | 812 | :: |
678 | 813 | |
679 | - ima1 = Ima() | |
680 | - result = ima1.genename("m63-1") | |
814 | + fn = Filenames() | |
815 | + result = fn.genename("m63-1") | |
816 | + | |
817 | + The index "1" is not necessary. So the command fn.genename("m63-") gives the same result. | |
818 | + | |
819 | + For example, you have 6 files m63-1.fit, m63-2.fit ... m63-6.fit. | |
820 | + You have to put one of the three file names as input of the method genename | |
821 | + and if you want to keep only files after the index 4: | |
822 | + | |
823 | + :: | |
824 | + | |
825 | + fn = Filenames() | |
826 | + result = fn.genename("m63-1", first=4) | |
827 | + | |
828 | + Indexes of 'first' and 'last' options can be negative (to start from end to begin). | |
681 | 829 | |
682 | 830 | """ |
683 | 831 | fitsname = self.fullfilename(fitsname) |
... | ... | @@ -766,7 +914,6 @@ class Filenames(FilenamesException, GuitastroTools): |
766 | 914 | indexes = [] |
767 | 915 | if len(ftmps) > 0: |
768 | 916 | k = len(genename+sep) |
769 | - indexes = [] | |
770 | 917 | #print(f"2 genename+sep = {genename+sep}") |
771 | 918 | #print(f"2 k = {k}") |
772 | 919 | nsuffix = len(suffix) |
... | ... | @@ -787,21 +934,212 @@ class Filenames(FilenamesException, GuitastroTools): |
787 | 934 | first = indexes[0] |
788 | 935 | if first[0] == "0": |
789 | 936 | ndigit = len(first) |
790 | - dico = {} | |
791 | - dico["dirname"] = dirname | |
792 | - dico["genename"] = genename | |
793 | - dico["sep"] = sep | |
794 | - dico["indexes"] = indexes | |
795 | - dico["suffix"] = suffix | |
796 | - dico["file_extension"] = file_extension | |
797 | - dico["ndigit"] = ndigit | |
798 | - return dico | |
799 | - | |
800 | - def _askopenfilename(self, title=""): | |
937 | + genname = {} | |
938 | + genname["dirname"] = dirname | |
939 | + genname["genename"] = genename | |
940 | + genname["sep"] = sep | |
941 | + genname["indexes"] = indexes | |
942 | + genname["suffix"] = suffix | |
943 | + genname["file_extension"] = file_extension | |
944 | + genname["ndigit"] = ndigit | |
945 | + # --- process optional parameters | |
946 | + if len(indexes) > 0: | |
947 | + first = int(genname["indexes"][0]) | |
948 | + n = int(genname["indexes"][-1]) | |
949 | + if "first" in kwargs.keys(): | |
950 | + bound = first | |
951 | + first = kwargs["first"] | |
952 | + if first < 0: | |
953 | + first = n + first + 1 | |
954 | + if first > n: | |
955 | + first = n | |
956 | + if first < bound: | |
957 | + first = bound | |
958 | + last = n | |
959 | + if "last" in kwargs.keys(): | |
960 | + last = kwargs["last"] | |
961 | + if last < 0: | |
962 | + last = n + last + 1 | |
963 | + if last < first: | |
964 | + last = first | |
965 | + if last > n: | |
966 | + last = n | |
967 | + indexes = [] | |
968 | + for index in genname["indexes"]: | |
969 | + rank = int(index) | |
970 | + if rank >= first and rank <= last: | |
971 | + if "indexes" in kwargs.keys(): | |
972 | + if rank in kwargs["indexes"]: | |
973 | + indexes.append(index) | |
974 | + else: | |
975 | + indexes.append(index) | |
976 | + genname["indexes"] = indexes | |
977 | + # --- | |
978 | + return genname | |
979 | + | |
980 | + | |
981 | + def innames(self, fitsname, **kwargs): | |
982 | + """Same method as genename() | |
983 | + """ | |
984 | + return self.genename(fitsname, **kwargs) | |
985 | + | |
986 | + def inoutnames(self, fitsname, outfilename, **kwargs): | |
987 | + """Generate file names informations to process a series of files. | |
988 | + | |
989 | + This method is the same than innames() but add the output names. | |
990 | + | |
991 | + Args: | |
992 | + fitsname: Any file name with or without path or extension. | |
993 | + outfilename: Generic name of the files that must be created later. | |
994 | + **kwargs: a dictionnary of optional parameters: | |
995 | + | |
996 | + * 'first': Lower index to keep indexes. | |
997 | + * 'last': Upper index to keep indexes. | |
998 | + * 'indexes': List of indexes to keep (integers). | |
999 | + | |
1000 | + Returns: | |
1001 | + A tupple of three elements. | |
1002 | + | |
1003 | + * A dictionary containing the following keys: | |
1004 | + | |
1005 | + * 'dirname': Path name | |
1006 | + * 'genename': Generic name of files | |
1007 | + * 'sep': Separator between generic name and indexes | |
1008 | + * 'indexes': List of indexes sorted increasing | |
1009 | + * 'file_extension': File extension | |
1010 | + * 'ndigit': Number of digits in case of indexes with leading zeros | |
1011 | + | |
1012 | + * A string that includes the path and the generic shortname. | |
1013 | + | |
1014 | + * The extension of the outpout files. | |
1015 | + | |
1016 | + For example, you have 6 files m63-1.fit, m63-2.fit ... m63-6.fit. | |
1017 | + You have to put one of the three file names as input of the method genename | |
1018 | + and if you want to keep only files after the index 4: | |
1019 | + | |
1020 | + :: | |
1021 | + | |
1022 | + fn = Filenames() | |
1023 | + result = fn.inoutnames("m63-1", "i", first=4) | |
1024 | + | |
1025 | + result can be ({'dirname': '/tmp', 'genename': 'm63', 'sep': '-', 'indexes': ['5', '6'], 'suffix': '', 'file_extension': '.fit', 'ndigit': 0}, '/tmp/j', '.fit') | |
1026 | + """ | |
1027 | + genename = self.innames(fitsname, **kwargs) | |
1028 | + # --- | |
1029 | + outfilename = self.fullfilename(outfilename) | |
1030 | + outfilegene, outfile_extension = os.path.splitext(outfilename) | |
1031 | + return genename, outfilegene, outfile_extension | |
1032 | + | |
1033 | + def outfilename(self, output=""): | |
1034 | + """Get or set the output file name | |
1035 | + | |
1036 | + Store the output current filename. Useful for image series or stacking. | |
1037 | + There is no verification if the file exists. | |
1038 | + | |
1039 | + Args: | |
1040 | + output: Any file name with or without path or extension. | |
1041 | + | |
1042 | + Returns: | |
1043 | + A string containing the full name of the file (path, shortname, extension). | |
1044 | + | |
1045 | + :: | |
1046 | + | |
1047 | + fn = Filenames() | |
1048 | + fullname = fn.outfilename("j1") | |
1049 | + | |
1050 | + """ | |
1051 | + fitsname = output | |
1052 | + if fitsname == "": | |
1053 | + # --- return the current output name | |
1054 | + res = self._outfilename | |
1055 | + else: | |
1056 | + # --- return a simulation of a output name | |
1057 | + genename = self.genename(fitsname) | |
1058 | + outfilename_short = genename["genename"] + genename["file_extension"] | |
1059 | + outfilename = os.path.join( genename["dirname"], outfilename_short) | |
1060 | + res = outfilename | |
1061 | + return res | |
1062 | + | |
1063 | + def indexnames(self, genename_in, outfilegene, outfile_extension, index, k=""): | |
1064 | + """Get input and output file names after using genename(). | |
1065 | + | |
1066 | + Generate input and output full file names. | |
1067 | + Before using this method, use genename() or innames() to generate the genename_in dictionary. | |
1068 | + There is no verification if the output file exists. | |
1069 | + | |
1070 | + Args: | |
1071 | + genename_in: Dictionary generated using the method genename(). | |
1072 | + outfilegene: Generic name (with ou withou path) of the output file | |
1073 | + outfile_extension: Extension of the output file | |
1074 | + index: Index if the intput file. Should be one of the elements of genename_in['indexes']. | |
1075 | + k: Index of the output file. If k is not given, it will be equal to index. | |
1076 | + | |
1077 | + Returns: | |
1078 | + A tupple of four elements. | |
1079 | + | |
1080 | + * A string of the short input file name. | |
1081 | + * A string of the short output file name. | |
1082 | + * A string of the full input file name. | |
1083 | + * A string of the full output file name. | |
1084 | + | |
1085 | + :: | |
1086 | + | |
1087 | + fn = Filenames() | |
1088 | + fn.path = '/tmp' | |
1089 | + gen = fn.innames("m63-1", first=4) | |
1090 | + shortin, shortout, fullin, fullout = fn.outfilename(gen, "/tmp/res/j", gen['indexes'][0], 1) | |
1091 | + | |
1092 | + The results should be shortin='m63-4.fit', shortout='j1.fit', shortin='/tmp/m63-4.fit', shortout='/tmp/res/j1.fit' | |
1093 | + """ | |
1094 | + filename_short = genename_in["genename"] + genename_in["sep"] + str(index) + genename_in["suffix"] + genename_in["file_extension"] | |
1095 | + filename = os.path.join( genename_in["dirname"], filename_short) | |
1096 | + if k=="": | |
1097 | + kstr = str(index) | |
1098 | + else: | |
1099 | + kstr = str(k) | |
1100 | + outgen = self.genename(outfilegene) | |
1101 | + outfname = os.path.join(outgen['dirname'],outgen['genename']) + kstr + outgen['suffix'] + outfile_extension | |
1102 | + basename = os.path.basename(outfname) | |
1103 | + #called_by = inspect.stack()[1][3] | |
1104 | + #print(f"ImaSeries.{called_by} {k}/{n} : {filename_short} -> {basename}") | |
1105 | + return filename_short, basename, filename, outfname | |
1106 | + | |
1107 | + def deletenames(self, fitsname, **kwargs): | |
1108 | + """Delete file names from a series of files. | |
1109 | + | |
1110 | + This method get the file names using innames(). | |
1111 | + | |
1112 | + Args: | |
1113 | + fitsname: Any file name with or without path or extension. | |
1114 | + **kwargs: a dictionnary of optional parameters: | |
1115 | + | |
1116 | + * 'first': Lower index to keep indexes. | |
1117 | + * 'last': Upper index to keep indexes. | |
1118 | + * 'indexes': List of indexes to keep (integers). | |
1119 | + | |
1120 | + Returns: | |
1121 | + List of deleted files. | |
1122 | + | |
1123 | + :: | |
1124 | + | |
1125 | + fn = Filenames() | |
1126 | + result = fn.deletenames("m63-1", first=4) | |
1127 | + | |
1128 | + result can be ({'dirname': '/tmp', 'genename': 'm63', 'sep': '-', 'indexes': ['5', '6'], 'suffix': '', 'file_extension': '.fit', 'ndigit': 0}, '/tmp/j', '.fit') | |
1129 | + """ | |
1130 | + fnames = [] | |
1131 | + for fname in self.itername(fitsname, **kwargs): | |
1132 | + os.remove(fname) | |
1133 | + fnames.append(fname) | |
1134 | + return fnames | |
1135 | + | |
1136 | + def _askopenfilename(self, title="", filetypes=""): | |
801 | 1137 | root = tk.Tk() |
802 | 1138 | root.withdraw() # pour ne pas afficher la fenรชtre Tk |
803 | 1139 | initialdir = self._image_dir |
804 | - fitsname = askopenfilename(title=title, initialdir=initialdir, filetypes = [("FITS","*.fit;*.fits;*.fts"),("All", "*")]) | |
1140 | + if filetypes == "": | |
1141 | + filetypes = [("FITS","*.fit;*.fits;*.fts"),("All", "*")] | |
1142 | + fitsname = askopenfilename(title=title, initialdir=initialdir, filetypes = filetypes) | |
805 | 1143 | if fitsname != "": |
806 | 1144 | filename, file_extension = os.path.splitext(fitsname) |
807 | 1145 | if file_extension=="": |
... | ... | @@ -810,11 +1148,13 @@ class Filenames(FilenamesException, GuitastroTools): |
810 | 1148 | root.destroy() |
811 | 1149 | return fitsname |
812 | 1150 | |
813 | - def _asksaveasfilename(self, title=""): | |
1151 | + def _asksaveasfilename(self, title="", filetypes=""): | |
814 | 1152 | root = tk.Tk() |
815 | 1153 | root.withdraw() # pour ne pas afficher la fenรชtre Tk |
816 | 1154 | initialdir = self._image_dir |
817 | - fitsname = asksaveasfilename(title=title, initialdir=initialdir, filetypes = [("FITS","*.fit;*.fits;*.fts"),("All", "*")]) | |
1155 | + if filetypes == "": | |
1156 | + filetypes = [("FITS","*.fit;*.fits;*.fts"),("All", "*")] | |
1157 | + fitsname = asksaveasfilename(title=title, initialdir=initialdir, filetypes = filetypes) | |
818 | 1158 | if fitsname != "": |
819 | 1159 | filename, file_extension = os.path.splitext(fitsname) |
820 | 1160 | if file_extension=="": |
... | ... | @@ -833,7 +1173,7 @@ class Filenames(FilenamesException, GuitastroTools): |
833 | 1173 | |
834 | 1174 | if __name__ == "__main__": |
835 | 1175 | |
836 | - default = 3 | |
1176 | + default = 4 | |
837 | 1177 | example = input(f"Select the example (0 to 3) ({default}) ") |
838 | 1178 | try: |
839 | 1179 | example = int(example) |
... | ... | @@ -879,9 +1219,24 @@ if __name__ == "__main__": |
879 | 1219 | param['date'] = "20221109" |
880 | 1220 | param['time'] = "235406123456" |
881 | 1221 | param['unit'] = "TNC" |
882 | - param['version'] = "1" | |
1222 | + param['version'] = 1 | |
883 | 1223 | param['channel'] = "CH1" |
884 | 1224 | param['id_seq'] = "0123456789" |
1225 | + param['plane'] = 1 | |
1226 | + param['frame'] = 1 | |
885 | 1227 | fname = fn.naming_set(**param) |
886 | 1228 | print(f"fname={fname}") |
887 | 1229 | param = fn.naming_get(fname) |
1230 | + | |
1231 | + if example == 4: | |
1232 | + """ | |
1233 | + """ | |
1234 | + fn = Filenames() | |
1235 | + for k in range(2, 10, 1): | |
1236 | + fname = f"i{k}.fit" | |
1237 | + print(fname) | |
1238 | + fname = fn.fullfilename(fname) | |
1239 | + with open(fname, "wt") as f: | |
1240 | + pass | |
1241 | + gen, out, outext = fn.inoutnames("i1", 'j', first=3, last=7) | |
1242 | + res = fn.indexnames(gen, out, outext, '3', 0) | ... | ... |
src/guitastro/ima.py
... | ... | @@ -67,9 +67,9 @@ from lmfit.models import Model # GaussianModel, LinearModel |
67 | 67 | import multiprocessing |
68 | 68 | |
69 | 69 | try: |
70 | - from .filenames import Filenames, FilenamesException | |
70 | + from .filenames import Filenames | |
71 | 71 | except: |
72 | - from filenames import Filenames, FilenamesException | |
72 | + from filenames import Filenames | |
73 | 73 | |
74 | 74 | try: |
75 | 75 | from .dates import Date |
... | ... | @@ -86,13 +86,6 @@ try: |
86 | 86 | except: |
87 | 87 | from wcs import Wcs |
88 | 88 | |
89 | -""" | |
90 | -try: | |
91 | - from .maps import Maps | |
92 | -except: | |
93 | - from maps import Maps | |
94 | -""" | |
95 | - | |
96 | 89 | try: |
97 | 90 | from .astrotables import AstroTable |
98 | 91 | except: |
... | ... | @@ -174,6 +167,32 @@ class Ima(ImaException, GuitastroTools): |
174 | 167 | |
175 | 168 | ima1.offset(100) |
176 | 169 | |
170 | + Note: | |
171 | + | |
172 | + The class Ima imports the following methods from the class Filenames. See the Filenames class documentation for these methods: | |
173 | + | |
174 | + * longitude | |
175 | + * namings | |
176 | + * naming | |
177 | + * naming_rules | |
178 | + * naming_ident | |
179 | + * naming_get | |
180 | + * naming_set | |
181 | + * path | |
182 | + * extension | |
183 | + * get_night | |
184 | + * fullfilename | |
185 | + * basename | |
186 | + * itername | |
187 | + * enumname | |
188 | + * genename | |
189 | + * genenames | |
190 | + * innames | |
191 | + * inoutnames | |
192 | + * outfilename | |
193 | + * indexnames | |
194 | + * deletenames | |
195 | + | |
177 | 196 | """ |
178 | 197 | |
179 | 198 | VERBOSE_NONE = 0 |
... | ... | @@ -231,6 +250,12 @@ class Ima(ImaException, GuitastroTools): |
231 | 250 | self.itername = fn.itername |
232 | 251 | self.enumname = fn.enumname |
233 | 252 | self.genename = fn.genename |
253 | + self.genenames = fn.genenames | |
254 | + self.innames = fn.innames | |
255 | + self.inoutnames = fn.inoutnames | |
256 | + self.outfilename = fn.outfilename | |
257 | + self.indexnames = fn.indexnames | |
258 | + self.deletenames = fn.deletenames | |
234 | 259 | self._askopenfilename = fn._askopenfilename |
235 | 260 | self._asksaveasfilename = fn._asksaveasfilename |
236 | 261 | ... | ... |
src/guitastro/imaseries.py
... | ... | @@ -5,12 +5,17 @@ |
5 | 5 | |
6 | 6 | import numpy as np |
7 | 7 | import os |
8 | -import inspect | |
8 | +#import inspect | |
9 | 9 | from astropy.wcs import WCS |
10 | 10 | import multiprocessing |
11 | 11 | import psutil |
12 | 12 | |
13 | 13 | try: |
14 | + from .filenames import Filenames | |
15 | +except: | |
16 | + from filenames import Filenames | |
17 | + | |
18 | +try: | |
14 | 19 | from .ima import Ima |
15 | 20 | except: |
16 | 21 | from ima import Ima |
... | ... | @@ -43,7 +48,35 @@ class ImaSeriesException(GuitastroException): |
43 | 48 | |
44 | 49 | |
45 | 50 | class ImaSeries(ImaSeriesException, GuitastroTools): |
51 | + """Image processing applied to a series of images. | |
52 | + | |
53 | + This class process a series of images to generate another series of images. | |
54 | + | |
55 | + The class ImaSeries imports the following methods from the class Filenames. See the Filenames class documentation for these methods: | |
56 | + | |
57 | + * longitude | |
58 | + * namings | |
59 | + * naming | |
60 | + * naming_rules | |
61 | + * naming_ident | |
62 | + * naming_get | |
63 | + * naming_set | |
64 | + * path | |
65 | + * extension | |
66 | + * get_night | |
67 | + * fullfilename | |
68 | + * basename | |
69 | + * itername | |
70 | + * enumname | |
71 | + * genename | |
72 | + * genenames | |
73 | + * innames | |
74 | + * inoutnames | |
75 | + * outfilename | |
76 | + * indexnames | |
77 | + * deletenames | |
46 | 78 | |
79 | + """ | |
47 | 80 | VERBOSE_NONE = 0 |
48 | 81 | VERBOSE_SPECIFIC = 1 |
49 | 82 | VERBOSE_DEBUG = 2 |
... | ... | @@ -57,9 +90,31 @@ class ImaSeries(ImaSeriesException, GuitastroTools): |
57 | 90 | self._outfilename = os.path.join(self._ima.path(), "noname"+self._ima.extension()) |
58 | 91 | self._ima.do_multiprocessing = False |
59 | 92 | self.do_multiprocessing = True |
60 | - | |
61 | - def longitude(self, longiau_deg:float): | |
62 | - self._ima.longitude(longiau_deg) | |
93 | + # --- import Filenames methods | |
94 | + fn = Filenames() | |
95 | + self.longitude = fn.longitude | |
96 | + self.namings = fn.namings | |
97 | + self.naming = fn.naming | |
98 | + self.naming_rules = fn.naming_rules | |
99 | + self.naming_ident = fn.naming_ident | |
100 | + self.naming_get = fn.naming_get | |
101 | + self.naming_set = fn.naming_set | |
102 | + self.path = fn.path | |
103 | + self.extension = fn.extension | |
104 | + self.get_night = fn.get_night | |
105 | + self.fullfilename = fn.fullfilename | |
106 | + self.basename = fn.basename | |
107 | + self.itername = fn.itername | |
108 | + self.enumname = fn.enumname | |
109 | + self.genename = fn.genename | |
110 | + self.genenames = fn.genenames | |
111 | + self.innames = fn.innames | |
112 | + self.inoutnames = fn.inoutnames | |
113 | + self.outfilename = fn.outfilename | |
114 | + self.indexnames = fn.indexnames | |
115 | + self.deletenames = fn.deletenames | |
116 | + self._askopenfilename = fn._askopenfilename | |
117 | + self._asksaveasfilename = fn._asksaveasfilename | |
63 | 118 | |
64 | 119 | def execute_process_type1(self, method_process, process_args, genename, outfilegene, outfile_extension): |
65 | 120 | """Generic method for multiprocesses |
... | ... | @@ -119,79 +174,6 @@ class ImaSeries(ImaSeriesException, GuitastroTools): |
119 | 174 | print(message) |
120 | 175 | |
121 | 176 | # ============================================= |
122 | - # Managing filenames | |
123 | - # ============================================= | |
124 | - | |
125 | - def path(self, path=""): | |
126 | - return self._ima.path(path) | |
127 | - | |
128 | - def extension(self, extension=""): | |
129 | - return self._ima.extension(extension) | |
130 | - | |
131 | - def outfilename(self, output=""): | |
132 | - basename = os.path.basename(self._outfilename) | |
133 | - shortname, file_extension = os.path.splitext(basename) | |
134 | - res = self._outfilename | |
135 | - if output != "": | |
136 | - res = shortname | |
137 | - return res | |
138 | - | |
139 | - def fullfilename(self,fitsname:str)->str: | |
140 | - return self._ima.path(fitsname) | |
141 | - | |
142 | - def basename(self,fitsname:str)->str: | |
143 | - return self._ima.basename(fitsname) | |
144 | - | |
145 | - def genename(self,fitsname:str)->str: | |
146 | - return self._ima.genename(fitsname) | |
147 | - | |
148 | - def inoutnames(self, fitsname, outfilename, **kwargs): | |
149 | - # --- | |
150 | - genename = self._ima.genename(fitsname) | |
151 | - n = len(genename["indexes"]) | |
152 | - # --- | |
153 | - first = 1 | |
154 | - if "first" in kwargs.keys(): | |
155 | - first = kwargs["first"] | |
156 | - if first > n: | |
157 | - first = n | |
158 | - end = n | |
159 | - if "end" in kwargs.keys(): | |
160 | - end = kwargs["end"] | |
161 | - if end < first: | |
162 | - end = first | |
163 | - if end > n: | |
164 | - end = n | |
165 | - indexes = [] | |
166 | - for index in genename["indexes"]: | |
167 | - rank = int(index) | |
168 | - if rank >= first and rank <= end: | |
169 | - indexes.append(index) | |
170 | - genename["indexes"] = indexes | |
171 | - # --- | |
172 | - outfilename = self._ima.fullfilename(outfilename) | |
173 | - outfilegene, outfile_extension = os.path.splitext(outfilename) | |
174 | - #print(f"genename={genename}") | |
175 | - #print(f"outfilegene={outfilegene}") | |
176 | - #print(f"outfile_extension={outfile_extension}") | |
177 | - return genename, outfilegene, outfile_extension | |
178 | - | |
179 | - def indexnames(self, genename, outfilegene, outfile_extension, index, k): | |
180 | - n = len(genename["indexes"]) | |
181 | - filename_short = genename["genename"] + genename["sep"] + index + genename["suffix"] + genename["file_extension"] | |
182 | - filename = os.path.join( genename["dirname"], filename_short) | |
183 | - outfname = outfilegene + str(k) + outfile_extension | |
184 | - basename = os.path.basename(outfname) | |
185 | - called_by = inspect.stack()[1][3] | |
186 | - print(f"ImaSeries.{called_by} {k}/{n} : {filename_short} -> {basename}") | |
187 | - return filename_short, basename, filename, outfname | |
188 | - | |
189 | - def deletenames(self, fitsname): | |
190 | - for fname in self._ima.itername(fitsname): | |
191 | - print(f"Delete = {fname}") | |
192 | - os.remove(fname) | |
193 | - | |
194 | - # ============================================= | |
195 | 177 | # Image processing (pixels are modified) |
196 | 178 | # ============================================= |
197 | 179 | ... | ... |
src/guitastro/imastack.py
... | ... | @@ -9,6 +9,11 @@ import datetime |
9 | 9 | import numpy as np |
10 | 10 | |
11 | 11 | try: |
12 | + from .filenames import Filenames | |
13 | +except: | |
14 | + from filenames import Filenames | |
15 | + | |
16 | +try: | |
12 | 17 | from .ima import Ima |
13 | 18 | except: |
14 | 19 | from ima import Ima |
... | ... | @@ -43,6 +48,35 @@ class ImaStackException(GuitastroException): |
43 | 48 | |
44 | 49 | |
45 | 50 | class ImaStack(ImaStackException, GuitastroTools): |
51 | + """Image processing applied to a series of images. | |
52 | + | |
53 | + This class process a series of images to generate only one image. | |
54 | + | |
55 | + The class ImaSeries imports the following methods from the class Filenames. See the Filenames class documentation for these methods: | |
56 | + | |
57 | + * longitude | |
58 | + * namings | |
59 | + * naming | |
60 | + * naming_rules | |
61 | + * naming_ident | |
62 | + * naming_get | |
63 | + * naming_set | |
64 | + * path | |
65 | + * extension | |
66 | + * get_night | |
67 | + * fullfilename | |
68 | + * basename | |
69 | + * itername | |
70 | + * enumname | |
71 | + * genename | |
72 | + * genenames | |
73 | + * innames | |
74 | + * inoutnames | |
75 | + * outfilename | |
76 | + * indexnames | |
77 | + * deletenames | |
78 | + | |
79 | + """ | |
46 | 80 | |
47 | 81 | VERBOSE_NONE = 0 |
48 | 82 | VERBOSE_SPECIFIC = 1 |
... | ... | @@ -55,6 +89,31 @@ class ImaStack(ImaStackException, GuitastroTools): |
55 | 89 | self._verbose_level = self.VERBOSE_NONE |
56 | 90 | self._longiau_deg = 0.0 |
57 | 91 | self._outfilename = os.path.join(self._ima.path(), "noname"+self._ima.extension()) |
92 | + # --- import Filenames methods | |
93 | + fn = Filenames() | |
94 | + self.longitude = fn.longitude | |
95 | + self.namings = fn.namings | |
96 | + self.naming = fn.naming | |
97 | + self.naming_rules = fn.naming_rules | |
98 | + self.naming_ident = fn.naming_ident | |
99 | + self.naming_get = fn.naming_get | |
100 | + self.naming_set = fn.naming_set | |
101 | + self.path = fn.path | |
102 | + self.extension = fn.extension | |
103 | + self.get_night = fn.get_night | |
104 | + self.fullfilename = fn.fullfilename | |
105 | + self.basename = fn.basename | |
106 | + self.itername = fn.itername | |
107 | + self.enumname = fn.enumname | |
108 | + self.genename = fn.genename | |
109 | + self.genenames = fn.genenames | |
110 | + self.innames = fn.innames | |
111 | + self.inoutnames = fn.inoutnames | |
112 | + self.outfilename = fn.outfilename | |
113 | + self.indexnames = fn.indexnames | |
114 | + self.deletenames = fn.deletenames | |
115 | + self._askopenfilename = fn._askopenfilename | |
116 | + self._asksaveasfilename = fn._asksaveasfilename | |
58 | 117 | |
59 | 118 | def longitude(self, longiau_deg:float): |
60 | 119 | self._ima.longitude(longiau_deg) | ... | ... |