let fastq_reads ?host ?name ?fragment_id r1 r2_opt : fastq_reads =     object (self)       val r1_file = single_file ?host r1       val r2_file_opt = Option.map r2_opt ~f:(single_file ?host)       method r1 = r1_file         (* workflow_node r1_file           ~name:(sprintf "File: %s" (Filename.basename r1_file#path)) *)       method r2 =  r2_file_opt         (* Option.map r2_file_opt ~f:(fun r2_file ->             workflow_node r2_file               ~name:(sprintf "File: %s" (Filename.basename r2_file#path))           ) *)       method paths = (r1, r2_opt)       method is_done =         Some (match r2_file_opt with           | Some r2 -> `And [r1_file#exists; r2#exists]           | None -> `And [r1_file#exists; r1_file#exists;])       method sample_name =         Option.value name ~default:(Filename.basename r1)       method fragment_id = fragment_id       method fragment_id_forced =         Option.value fragment_id ~default:(Filename.basename r1)       method escaped_sample_name =         String.map self#sample_name ~f:(function           | '0' .. '9' | 'a' .. 'z' | 'A' .. 'Z' | '-' | '_' as c -> c           | other -> '_')     end