Commit 852c1347aa30f7487ba504091fc47b0d1fc7158c
1 parent
9fe16961
Exists in
master
Add wildcards in filenames.
Showing
2 changed files
with
252 additions
and
45 deletions
Show diff stats
src/guitastro/dates.py
... | ... | @@ -263,9 +263,9 @@ class Date(GuitastroTools): |
263 | 263 | |
264 | 264 | .. note:: Prefer using objdate.date() followed by objdate.jd(). |
265 | 265 | """ |
266 | - # --- First we do not process if date is ever a Date object | |
266 | + # --- First we compute jd if date is ever a Date object | |
267 | 267 | if (isinstance(date, Date)): |
268 | - return date | |
268 | + date = date.jd() | |
269 | 269 | # --- Decode the date |
270 | 270 | jd = 0 |
271 | 271 | init_dateformat = 0 | ... | ... |
src/guitastro/filenames.py
... | ... | @@ -215,6 +215,8 @@ class FileNames(FileNamesException, GuitastroTools): |
215 | 215 | self._verbose_level = self.VERBOSE_NONE |
216 | 216 | self._longiau_deg = 0.0 |
217 | 217 | self._naming = self.NAMING_NONE |
218 | + self._pathing = self.PATHING_NONE | |
219 | + self._pathnaming = self._naming | |
218 | 220 | self._outfilename = os.path.join(self._image_dir, "noname"+self.extension()) |
219 | 221 | # --- naming_rule |
220 | 222 | if len(args) > 0 : |
... | ... | @@ -348,7 +350,7 @@ class FileNames(FileNamesException, GuitastroTools): |
348 | 350 | texte += "Example: L0_20221109_235406123456_1_TNC_CH1_0123456789_001_001\n" |
349 | 351 | texte += "UUU, CCC are accronyms (string)\n" |
350 | 352 | texte += "V, IIIIIIIIII, PPP, FFF are digits (int)\n" |
351 | - texte += "CCC is a Channel for L0,L1 ftype levels but should by the Album for L2 level" | |
353 | + texte += "CCC is a Channel for L0,L1 ftype levels but should be the Album for L2 level" | |
352 | 354 | return texte |
353 | 355 | |
354 | 356 | def __naming_rules_ros1(self, section): |
... | ... | @@ -597,29 +599,48 @@ class FileNames(FileNamesException, GuitastroTools): |
597 | 599 | fname = fn.naming_set(**param) |
598 | 600 | |
599 | 601 | The answer should be L0_20221109_235406123456_TNC_1_CH1_0123456789_001_001. |
600 | - If param['date'] is "*" then the date and time will be the current UTC time. | |
602 | + For naming = "PyROS.1", if param['date'] is "*" then the date and time will be the current UTC time. | |
603 | + | |
604 | + If a key is lacking in the dictionary, a wildcard is replaced. Useful to get a glob. | |
601 | 605 | """ |
602 | 606 | see_rules = self._see_naming_rules |
607 | + # --- wilcards | |
608 | + if self._naming == self.NAMING_NONE: | |
609 | + wildcard = "*" | |
610 | + elif self._naming == self.NAMING_PYROS1: | |
611 | + wildcard = "??_????????_????????????_?_???_???_??????????_???_???" | |
612 | + elif self._naming == self.NAMING_ROS1: | |
613 | + wildcard = "??_????????_????????????_??????_????????" | |
614 | + # --- | |
615 | + na = len(args) | |
616 | + nk = len(kwargs) | |
603 | 617 | if self._naming == self.NAMING_NONE: |
604 | - fname = args[0] | |
618 | + if na > 0: | |
619 | + fname = args[0] | |
605 | 620 | if self._naming == self.NAMING_PYROS1: |
606 | - if len(args) > 0: | |
607 | - if isinstance(args[0],dict): | |
621 | + if na > 0: | |
622 | + # case the dict is not **kwargs but *args | |
623 | + if isinstance(args[0], dict): | |
608 | 624 | kwargs = args[0] |
609 | - elif len(kwargs)==0: | |
610 | - return self.naming_rules() | |
625 | + nk = len(kwargs) | |
626 | + else: | |
627 | + texte = "Dictionary of input parameters not found " + see_rules | |
628 | + raise FileNamesException(FileNamesException.BAD_PARAM, texte) | |
629 | + elif nk == 0: | |
630 | + return wildcard | |
611 | 631 | # -- read kwargs |
632 | + wildcards = wildcard.split("_") | |
612 | 633 | param = {} |
613 | - param['ftype'] = "" | |
614 | - param['date'] = "" | |
615 | - param['time'] = "" | |
616 | - param['version'] = "" | |
617 | - param['unit'] = "" | |
618 | - param['channel'] = "" | |
619 | - param['id_seq'] = "" | |
620 | - param['plane'] = "" | |
621 | - param['frame'] = "" | |
622 | - if len(kwargs) > 0: | |
634 | + param['ftype'] = wildcards[0] | |
635 | + param['date'] = wildcards[1] | |
636 | + param['time'] = wildcards[2] | |
637 | + param['version'] = wildcards[3] | |
638 | + param['unit'] = wildcards[4] | |
639 | + param['channel'] = wildcards[5] | |
640 | + param['id_seq'] = wildcards[6] | |
641 | + param['plane'] = wildcards[7] | |
642 | + param['frame'] = wildcards[8] | |
643 | + if nk > 0: | |
623 | 644 | for key, val in kwargs.items(): |
624 | 645 | if key in param.keys(): |
625 | 646 | param[key] = val |
... | ... | @@ -630,13 +651,16 @@ class FileNames(FileNamesException, GuitastroTools): |
630 | 651 | raise FileNamesException(FileNamesException.EMPTY_STRING, texte) |
631 | 652 | # --- verify ftype |
632 | 653 | if isinstance(param['ftype'],str): |
633 | - if param['ftype'] not in self._naming_0_stypes: | |
634 | - texte = f"File type {param['ftype']} not found amongst {self._naming_0_stypes}" + see_rules | |
635 | - raise FileNamesException(FileNamesException.BAD_PARAM, texte) | |
654 | + if param['ftype'] != wildcards[0]: | |
655 | + if param['ftype'] not in self._naming_0_stypes: | |
656 | + texte = f"File type {param['ftype']} not found amongst {self._naming_0_stypes}" + see_rules | |
657 | + raise FileNamesException(FileNamesException.BAD_PARAM, texte) | |
636 | 658 | # --- verify date |
637 | 659 | valid = False |
638 | 660 | if isinstance(param['date'],str): |
639 | - if len(param['date']) == 8: | |
661 | + if param['date'] == wildcards[1]: | |
662 | + valid = True | |
663 | + elif len(param['date']) == 8: | |
640 | 664 | if param['date'].isdigit(): |
641 | 665 | valid = True |
642 | 666 | elif param['date'] == "*": |
... | ... | @@ -652,7 +676,9 @@ class FileNames(FileNamesException, GuitastroTools): |
652 | 676 | # --- verify time |
653 | 677 | valid = False |
654 | 678 | if isinstance(param['time'],str): |
655 | - if len(param['time']) == 12: | |
679 | + if param['time'] == wildcards[2]: | |
680 | + valid = True | |
681 | + elif len(param['time']) == 12: | |
656 | 682 | if param['time'].isdigit(): |
657 | 683 | valid = True |
658 | 684 | if valid == False: |
... | ... | @@ -661,7 +687,9 @@ class FileNames(FileNamesException, GuitastroTools): |
661 | 687 | # --- verify version |
662 | 688 | valid = False |
663 | 689 | if isinstance(param['version'],str): |
664 | - if len(param['version']) == 1: | |
690 | + if param['version'] == wildcards[3]: | |
691 | + valid = True | |
692 | + elif len(param['version']) == 1: | |
665 | 693 | valid = True |
666 | 694 | elif isinstance(param['version'],int): |
667 | 695 | param['version'] = f"{param['version']:01d}" |
... | ... | @@ -672,7 +700,9 @@ class FileNames(FileNamesException, GuitastroTools): |
672 | 700 | # --- verify unit |
673 | 701 | valid = False |
674 | 702 | if isinstance(param['unit'],str): |
675 | - if len(param['unit']) == 3: | |
703 | + if param['unit'] == wildcards[4]: | |
704 | + valid = True | |
705 | + elif len(param['unit']) == 3: | |
676 | 706 | valid = True |
677 | 707 | if valid == False: |
678 | 708 | texte = f"Unit {param['unit']} must be a string of 3 characters" + see_rules |
... | ... | @@ -680,7 +710,9 @@ class FileNames(FileNamesException, GuitastroTools): |
680 | 710 | # --- verify channel |
681 | 711 | valid = False |
682 | 712 | if isinstance(param['channel'],str): |
683 | - if len(param['channel']) == 3: | |
713 | + if param['channel'] == wildcards[5]: | |
714 | + valid = True | |
715 | + elif len(param['channel']) == 3: | |
684 | 716 | valid = True |
685 | 717 | if valid == False: |
686 | 718 | texte = f"Channel {param['channel']} must be a string of 3 characters" + see_rules |
... | ... | @@ -688,7 +720,9 @@ class FileNames(FileNamesException, GuitastroTools): |
688 | 720 | # --- verify id_seq |
689 | 721 | valid = False |
690 | 722 | if isinstance(param['id_seq'],str): |
691 | - if len(param['id_seq']) == 10: | |
723 | + if param['id_seq'] == wildcards[6]: | |
724 | + valid = True | |
725 | + elif len(param['id_seq']) == 10: | |
692 | 726 | valid = True |
693 | 727 | elif isinstance(param['id_seq'],int): |
694 | 728 | param['id_seq'] = f"{param['id_seq']:010d}" |
... | ... | @@ -699,7 +733,9 @@ class FileNames(FileNamesException, GuitastroTools): |
699 | 733 | # --- verify plane |
700 | 734 | valid = False |
701 | 735 | if isinstance(param['plane'],str): |
702 | - if len(param['plane']) == 3: | |
736 | + if param['plane'] == wildcards[7]: | |
737 | + valid = True | |
738 | + elif len(param['plane']) == 3: | |
703 | 739 | valid = True |
704 | 740 | elif isinstance(param['plane'],int): |
705 | 741 | param['plane'] = f"{param['plane']:03d}" |
... | ... | @@ -710,7 +746,9 @@ class FileNames(FileNamesException, GuitastroTools): |
710 | 746 | # --- verify frame |
711 | 747 | valid = False |
712 | 748 | if isinstance(param['frame'],str): |
713 | - if len(param['frame']) == 3: | |
749 | + if param['frame'] == wildcards[8]: | |
750 | + valid = True | |
751 | + elif len(param['frame']) == 3: | |
714 | 752 | valid = True |
715 | 753 | elif isinstance(param['frame'],int): |
716 | 754 | param['frame'] = f"{param['frame']:03d}" |
... | ... | @@ -721,19 +759,25 @@ class FileNames(FileNamesException, GuitastroTools): |
721 | 759 | # --- form final file name |
722 | 760 | fname = param['ftype']+"_"+param['date']+"_"+param['time']+"_"+param['version']+"_"+param['unit']+"_"+param['channel']+"_"+param['id_seq']+"_"+param['plane']+"_"+param['frame'] |
723 | 761 | if self._naming == self.NAMING_ROS1: |
724 | - if len(args) > 0: | |
725 | - if isinstance(args[0],dict): | |
762 | + if na > 0: | |
763 | + # case the dict is not **kwargs but *args | |
764 | + if isinstance(args[0], dict): | |
726 | 765 | kwargs = args[0] |
727 | - elif len(kwargs)==0: | |
728 | - return self.naming_rules() | |
766 | + nk = len(kwargs) | |
767 | + else: | |
768 | + texte = "Dictionary of input parameters not found " + see_rules | |
769 | + raise FileNamesException(FileNamesException.BAD_PARAM, texte) | |
770 | + elif nk == 0: | |
771 | + return wildcard | |
729 | 772 | # -- read kwargs |
773 | + wildcards = wildcard.split("_") | |
730 | 774 | param = {} |
731 | - param['ftype'] = "" | |
732 | - param['date'] = "" | |
733 | - param['time'] = "" | |
734 | - param['id_scene'] = "" | |
735 | - param['unit'] = "" | |
736 | - if len(kwargs) > 0: | |
775 | + param['ftype'] = wildcards[0] | |
776 | + param['date'] = wildcards[1] | |
777 | + param['time'] = wildcards[2] | |
778 | + param['id_scene'] = "????????????" | |
779 | + param['unit'] = "??" | |
780 | + if nk > 0: | |
737 | 781 | for key, val in kwargs.items(): |
738 | 782 | if key in param.keys(): |
739 | 783 | param[key] = val |
... | ... | @@ -744,13 +788,17 @@ class FileNames(FileNamesException, GuitastroTools): |
744 | 788 | raise FileNamesException(FileNamesException.EMPTY_STRING, texte) |
745 | 789 | # --- verify ftype |
746 | 790 | if isinstance(param['ftype'],str): |
791 | + if param['ftype'] == wildcards[0]: | |
792 | + valid = True | |
747 | 793 | if param['ftype'] not in self._naming_1_stypes: |
748 | 794 | texte = f"File type {param['ftype']} not found amongst {self._naming_1_stypes}" + see_rules |
749 | 795 | raise FileNamesException(FileNamesException.BAD_PARAM, texte) |
750 | 796 | # --- verify date |
751 | 797 | valid = False |
752 | 798 | if isinstance(param['date'],str): |
753 | - if len(param['date']) == 8: | |
799 | + if param['date'] == wildcards[1]: | |
800 | + valid = True | |
801 | + elif len(param['date']) == 8: | |
754 | 802 | if param['date'].isdigit(): |
755 | 803 | valid = True |
756 | 804 | elif param['date'] == "*": |
... | ... | @@ -766,6 +814,8 @@ class FileNames(FileNamesException, GuitastroTools): |
766 | 814 | # --- verify time |
767 | 815 | valid = False |
768 | 816 | if isinstance(param['time'],str): |
817 | + if param['time'] == wildcards[2]: | |
818 | + valid = True | |
769 | 819 | if len(param['time']) == 9: |
770 | 820 | if param['time'].isdigit(): |
771 | 821 | valid = True |
... | ... | @@ -775,7 +825,9 @@ class FileNames(FileNamesException, GuitastroTools): |
775 | 825 | # --- verify id_scene |
776 | 826 | valid = False |
777 | 827 | if isinstance(param['id_scene'],str): |
778 | - if len(param['id_scene']) == 12: | |
828 | + if param['id_scene'] == wildcards[3]: | |
829 | + valid = True | |
830 | + elif len(param['id_scene']) == 12: | |
779 | 831 | valid = True |
780 | 832 | elif isinstance(param['id_scene'],int): |
781 | 833 | param['id_scene'] = f"{param['id_scene']:012d}" |
... | ... | @@ -786,7 +838,9 @@ class FileNames(FileNamesException, GuitastroTools): |
786 | 838 | # --- verify unit |
787 | 839 | valid = False |
788 | 840 | if isinstance(param['unit'],str): |
789 | - if len(param['unit']) == 2: | |
841 | + if param['id_scene'] == wildcards[4]: | |
842 | + valid = True | |
843 | + elif len(param['unit']) == 2: | |
790 | 844 | valid = True |
791 | 845 | if valid == False: |
792 | 846 | texte = f"Unit {param['unit']} must be a string of 2 characters" + see_rules |
... | ... | @@ -795,6 +849,33 @@ class FileNames(FileNamesException, GuitastroTools): |
795 | 849 | fname = param['ftype']+"_"+param['date']+"_"+param['time']+"_"+param['id_scene'][:6]+"_"+param['id_scene'][6:]+param['unit'] |
796 | 850 | return fname |
797 | 851 | |
852 | + def naming_date(self, date:Date) -> str: | |
853 | + """Compute dates in various string formats. | |
854 | + | |
855 | + It is a tool that returns a dictionary allowing to form names. | |
856 | + """ | |
857 | + date = Date(date); | |
858 | + digits = date.digits(6) | |
859 | + d = {} | |
860 | + d['iso'] = date.iso(6, 'T') | |
861 | + d['iso_'] = d['iso'].replace("-","_") | |
862 | + d['iso_'] = d['iso_'].replace(":","_") | |
863 | + d['iso_'] = d['iso_'].replace(".","_") | |
864 | + d['iso_'] = d['iso_'].replace("T","_") | |
865 | + d['yyyy'] = digits[:4] | |
866 | + d['mm'] = digits[4:6] | |
867 | + d['dd'] = digits[6:8] | |
868 | + d['hh'] = digits[8:10] | |
869 | + d['mm'] = digits[10:12] | |
870 | + d['ss'] = digits[12:14] | |
871 | + d['yyyymmdd'] = digits[:8] | |
872 | + d['hhmmss'] = digits[8:14] | |
873 | + d['hhmmssssssss'] = d['hhmmss'] + digits[15:21] | |
874 | + return d | |
875 | + | |
876 | + def naming_wildcards(self, prepath, pkw:dict, nkw:dict, extension="") -> str: | |
877 | + pass | |
878 | + | |
798 | 879 | # ============================================= |
799 | 880 | # Managing pathing |
800 | 881 | # ============================================= |
... | ... | @@ -1103,6 +1184,108 @@ class FileNames(FileNamesException, GuitastroTools): |
1103 | 1184 | pname = os.path.join(yyyy, mm, dd) |
1104 | 1185 | return pname |
1105 | 1186 | |
1187 | + | |
1188 | + # ============================================= | |
1189 | + # Managing pathnaming (path + names) | |
1190 | + # ============================================= | |
1191 | + | |
1192 | + def pathnamings(self): | |
1193 | + """List of pathnamings | |
1194 | + | |
1195 | + Path and file names can be formed using given rules. | |
1196 | + This method returns a list of all possible pathnaming rules. | |
1197 | + The pathanming should be one amongst the namings (pathnaming and naming shared the same symbols). | |
1198 | + """ | |
1199 | + return self._naming_list | |
1200 | + | |
1201 | + def pathnaming(self, *args): | |
1202 | + """Get the current pathnaming of files or set a new one | |
1203 | + | |
1204 | + The choice of a pathnaming will set the pathing and the naming. | |
1205 | + | |
1206 | + Args: | |
1207 | + *args: a string with a new pathnaming of files. | |
1208 | + See the list using pathnamings(). | |
1209 | + | |
1210 | + Returns: | |
1211 | + The new selected pathnaming. | |
1212 | + | |
1213 | + Example: To get the current pathnaming | |
1214 | + | |
1215 | + :: | |
1216 | + | |
1217 | + fn = FileNames() | |
1218 | + pathnaming = fn.pathnaming() | |
1219 | + | |
1220 | + Example: To select a new pathnaming | |
1221 | + | |
1222 | + :: | |
1223 | + | |
1224 | + fn = FileNames() | |
1225 | + fn.pathnaming("PyROS.1") | |
1226 | + | |
1227 | + """ | |
1228 | + if len(args) >= 1: | |
1229 | + new_naming = args[0] | |
1230 | + new_namingu = new_naming.upper() | |
1231 | + n = len(self._naming_list) | |
1232 | + found = False | |
1233 | + for k in range(n): | |
1234 | + naming = self._naming_list[k] | |
1235 | + if naming.upper() == new_namingu: | |
1236 | + self._pathnaming = k | |
1237 | + found = True | |
1238 | + if found == False: | |
1239 | + texte = f"{new_naming} not found amongst {self._naming_list}" | |
1240 | + raise FileNamesException(FileNamesException.NO_NAMING_FOUND, texte) | |
1241 | + self._naming = self._pathnaming | |
1242 | + if self._pathnaming == self.NAMING_PYROS1: | |
1243 | + self._pathing = self.PATHING_YYYY_MM_DD | |
1244 | + return self._naming_list[self._pathnaming] | |
1245 | + | |
1246 | + def pathnaming_set(self, prepath, pkw:dict, nkw:dict, extension="") -> str: | |
1247 | + """Set a full file name formed by input parameters according the current pathnaming | |
1248 | + | |
1249 | + Args: | |
1250 | + *args: a pathname if naming is ''. | |
1251 | + **kwargs: a dictionnary of parameters that depends on the pathing. | |
1252 | + | |
1253 | + Returns: | |
1254 | + The full file name with no extension. | |
1255 | + | |
1256 | + Example: | |
1257 | + | |
1258 | + :: | |
1259 | + | |
1260 | + fn = FileNames() | |
1261 | + fn.pathnaming("PyROS.1") | |
1262 | + fn.longitude(45.678) | |
1263 | + prepath = "/tmp" | |
1264 | + date = "2021-10-26T13:45:23" | |
1265 | + fnd = fn.naming_date(date) | |
1266 | + pparam = {} | |
1267 | + pparam['date'] = fnd['iso'] | |
1268 | + pparam['night'] = True | |
1269 | + fparam = {} | |
1270 | + fparam['ftype'] = "L0" | |
1271 | + fparam['date'] = fnd['yyyymmdd'] | |
1272 | + fparam['time'] = fnd['hhmmssssssss'] | |
1273 | + fparam['version'] = "1" | |
1274 | + fparam['unit'] = "TNC" | |
1275 | + fparam['channel'] = "CH1" | |
1276 | + fparam['id_seq'] = 123456789 | |
1277 | + fparam['plane'] = 1 | |
1278 | + fparam['frame'] = 1 | |
1279 | + fullname = fn.pathnaming_set(prepath, pparam, fparam, ".fits") | |
1280 | + | |
1281 | + The answer should be '/tmp\\2021\\10\\26\\L0_20211026_134522999983_1_TNC_CH1_0123456789_001_001.fits' | |
1282 | + """ | |
1283 | + if self._pathnaming == self.NAMING_PYROS1: | |
1284 | + path = self.pathing_set(**pkw) | |
1285 | + fname = self.naming_set(**nkw) | |
1286 | + fullname = os.path.join(prepath, path, fname) + extension | |
1287 | + return fullname | |
1288 | + | |
1106 | 1289 | # ============================================= |
1107 | 1290 | # Managing filenames |
1108 | 1291 | # ============================================= |
... | ... | @@ -1815,8 +1998,8 @@ class FileNames(FileNamesException, GuitastroTools): |
1815 | 1998 | |
1816 | 1999 | if __name__ == "__main__": |
1817 | 2000 | |
1818 | - default = 5 | |
1819 | - example = input(f"Select the example (0 to 5) ({default}) ") | |
2001 | + default = 6 | |
2002 | + example = input(f"Select the example (0 to 6) ({default}) ") | |
1820 | 2003 | try: |
1821 | 2004 | example = int(example) |
1822 | 2005 | except: |
... | ... | @@ -1906,3 +2089,27 @@ if __name__ == "__main__": |
1906 | 2089 | param['night'] = True |
1907 | 2090 | pname = fn.pathing_set(**param) |
1908 | 2091 | |
2092 | + if example == 6: | |
2093 | + """ | |
2094 | + """ | |
2095 | + fn = FileNames() | |
2096 | + fn.pathnaming("PyROS.1") | |
2097 | + fn.longitude(45.678) | |
2098 | + prepath = "/tmp" | |
2099 | + date = "2021-10-26T13:45:23" | |
2100 | + fnd = fn.naming_date(date) | |
2101 | + pparam = {} | |
2102 | + pparam['date'] = fnd['iso'] | |
2103 | + pparam['night'] = True | |
2104 | + fparam = {} | |
2105 | + fparam['ftype'] = "L0" | |
2106 | + fparam['date'] = fnd['yyyymmdd'] | |
2107 | + fparam['time'] = fnd['hhmmssssssss'] | |
2108 | + fparam['version'] = "1" | |
2109 | + fparam['unit'] = "TNC" | |
2110 | + fparam['channel'] = "CH1" | |
2111 | + fparam['id_seq'] = 123456789 | |
2112 | + fparam['plane'] = 1 | |
2113 | + fparam['frame'] = 1 | |
2114 | + fullname = fn.pathnaming_set(prepath, pparam, fparam) | |
2115 | + print(f"fullname={fullname}") | |
1909 | 2116 | \ No newline at end of file | ... | ... |