@@ -394,11 +394,13 @@ def check_root_attr(f, v):
394394 result_array += test_attr (f , v , "required" , "openPMD" , np .string_ , "^[0-9]+\.[0-9]+\.[0-9]+$" )
395395 result_array += test_attr (f , v , "required" , "openPMDextension" , np .uint32 )
396396 result_array += test_attr (f , v , "required" , "basePath" , np .string_ , "^\/data\/\%T\/$" )
397- result_array += test_attr (f , v , "required" , "meshesPath" , np .string_ )
398- result_array += test_attr (f , v , "required" , "particlesPath" , np .string_ )
399397 result_array += test_attr (f , v , "required" , "iterationEncoding" , np .string_ , "^groupBased|fileBased$" )
400398 result_array += test_attr (f , v , "required" , "iterationFormat" , np .string_ )
401399
400+ # optional but required for data
401+ result_array += test_attr (f , v , "optional" , "meshesPath" , np .string_ )
402+ result_array += test_attr (f , v , "optional" , "particlesPath" , np .string_ )
403+
402404 # groupBased iteration encoding needs to match basePath
403405 if result_array [0 ] == 0 :
404406 if f .attrs ["iterationEncoding" ].decode () == "groupBased" :
@@ -548,35 +550,45 @@ def check_meshes(f, iteration, v, extensionStates):
548550 # First element : number of errors
549551 # Second element : number of warnings
550552 result_array = np .array ([ 0 , 0 ])
551-
553+
552554 # Find the path to the data
553555 base_path = "/data/%s/" % iteration
554556 valid , meshes_path = get_attr (f , "meshesPath" )
555- if not valid :
556- print ("Error: `meshesPath` is missing or malformed in '/'" )
557- return ( np .array ([1 , 0 ]) )
558- meshes_path = meshes_path .decode ()
559-
560- if os .path .join ( base_path , meshes_path ) != ( base_path + meshes_path ):
561- print ("Error: `basePath`+`meshesPath` seems to be malformed "
562- "(is `basePath` absolute and ends on a `/` ?)" )
563- return ( np .array ([1 , 0 ]) )
557+ if not valid and v :
558+ print ("`meshesPath` attribute is missing in '/' "
559+ "(will not search for mesh records)" )
560+ meshes_path = None
564561 else :
565- full_meshes_path = (base_path + meshes_path ).encode ('ascii' )
566- # Find all the meshes
567- try :
568- list_meshes = list (f [full_meshes_path ].keys ())
569- except KeyError :
570- list_meshes = []
571- print ( "Iteration %s : found %d meshes"
572- % ( iteration , len (list_meshes ) ) )
562+ meshes_path = meshes_path .decode ()
563+
564+ if meshes_path :
565+ if os .path .join ( base_path , meshes_path ) != ( base_path + meshes_path ):
566+ print ("Error: `basePath`+`meshesPath` seems to be malformed "
567+ "(is `basePath` absolute and ends on a `/` ?)" )
568+ return ( np .array ([1 , 0 ]) )
569+ else :
570+ full_meshes_path = (base_path + meshes_path ).encode ('ascii' )
571+ # if set, a directory must exist with this name
572+ if not full_meshes_path in f :
573+ print ("Error: `basePath`+`meshesPath` are set but path '{0}' "
574+ "does not exist in file!" .format (full_meshes_path ))
575+ return ( np .array ([1 , 0 ]) )
576+ # Find all the meshes
577+ try :
578+ list_meshes = list (f [full_meshes_path ].keys ())
579+ except KeyError :
580+ list_meshes = []
581+ print ( "Iteration %s : found %d meshes"
582+ % ( iteration , len (list_meshes ) ) )
583+ else :
584+ list_meshes = []
573585
574586 # Check for the attributes of the STANDARD.md
575587 for field_name in list_meshes :
576588 field = f [full_meshes_path + field_name .encode ('ascii' )]
577589
578590 result_array += test_record (f [full_meshes_path ], field_name )
579-
591+
580592 # General attributes of the record
581593 result_array += test_attr (field , v , "required" ,
582594 "unitDimension" , np .ndarray , np .float64 )
@@ -702,20 +714,38 @@ def check_particles(f, iteration, v, extensionStates) :
702714 result_array = np .array ([ 0 , 0 ])
703715
704716 # Find the path to the data
705- base_path = ( "/data/%s/" % iteration ). encode ( 'ascii' )
717+ base_path = "/data/%s/" % iteration
706718 valid , particles_path = get_attr (f , "particlesPath" )
707- if os . path . join ( base_path , particles_path ) != \
708- ( base_path + particles_path ) :
709- print ("Error: `basePath`+` particlesPath` seems to be malformed "
710- "(is `basePath` absolute and ends on a `/` ? )" )
711- return ( np . array ([ 1 , 0 ]) )
719+
720+ if not valid and v :
721+ print ("` particlesPath` attribute is missing in '/' "
722+ "(will not search for particle records )" )
723+ particles_path = None
712724 else :
713- full_particle_path = base_path + particles_path
714- # Find all the particle species
715- try :
716- list_species = list (f [full_particle_path ].keys ())
717- except KeyError :
718- list_species = []
725+ particles_path = particles_path .decode ()
726+
727+ if particles_path :
728+ if os .path .join ( base_path , particles_path ) != \
729+ ( base_path + particles_path ) :
730+ print ("Error: `basePath`+`particlesPath` seems to be malformed "
731+ "(is `basePath` absolute and ends on a `/` ?)" )
732+ return (np .array ([1 , 0 ]))
733+ else :
734+ full_particle_path = (base_path + particles_path ).encode ('ascii' )
735+ # if set, a directory must exist with this name
736+ if not full_particle_path in f :
737+ print ("Error: `basePath`+`particlesPath` are set but path "
738+ "'{0}' does not exist in file!" .format (
739+ full_particle_path ))
740+ return (np .array ([1 , 0 ]))
741+ # Find all the particle species
742+ try :
743+ list_species = list (f [full_particle_path ].keys ())
744+ except KeyError :
745+ list_species = []
746+ else :
747+ list_species = []
748+
719749 print ( "Iteration %s : found %d particle species"
720750 % ( iteration , len (list_species ) ) )
721751
0 commit comments