#!/usr/bin/env python ######################################################################## ## 05/2018 Justin Rajendra ## do stuff with info from bids json file or any json file ## system libraries import sys, os, glob, subprocess, csv, re, argparse, signal, textwrap, json from collections import OrderedDict from afnipy import afni_base ######################################################################## ## functions and classes oh my? ################################## ## print in color def printNcolor(message,message2="",color="0",bg="0",style="0"): """Print to terminal in some colors and style printNcolor("hello",color="White",bg="Blue",style="Bold") You can put 2 messages. The first will have color, the second won't. Color options are below. And may be different on different systems. If the input colors are not matched in the dictionary, it will output as the standard. """ ## add more colors later? color_dict = {"Black":"30","Red":"31","Green":"32","Yellow":"33", "Blue":"34","Purple":"35","Cyan":"36","White":"37"} bg_dict = {"Black":"40","Red":"41","Green":"42","Yellow":"43", "Blue":"44","Purple":"45","Cyan":"46","White":"47"} style_dict = {"None":"0","Bold":"1","Underline":"2","Negative1":"3", "Negative2":"5"} ## convert to strings color = str(color) ; style = str(style) ; bg = str(bg) ## look up or default to nothing color = color_dict.get(color,"0") bg = bg_dict.get(bg,"0") style = style_dict.get(style,"0") ## print to terminal print("\033["+style+";"+color+";"+bg+"m"+message+"\033[0;0m"+message2) ################################## ## check if a table is rectangular def data_is_rect(mdata): """check if a table is rectangular return 1 for rect, 0 for not rect """ if mdata == None: return 1 if len(mdata) == 0: return 1 rlen = len(mdata[0]) for row in mdata: if len(row) != rlen: return 0 return 1 ################################## ## run some command or give error def exec_or_error(cmd, error_msg="See above!!!", showerr=1, showcmd=1): """return text output from the given command if showcmd, print the cmd if showerr and there is a command error, show it This will exit on status other than 0 so BE CAREFUL!!! """ status, cmd_output, error_out = afni_base.simple_shell_exec(cmd,capture=1) if showcmd: print(cmd) if showerr: print(error_out) if status != 0: if error_msg != "See above!!!": error_msg = error_msg+"!!!" printNcolor("** ERROR:"," "+error_msg,"Red","White","Bold") sys.exit(1) return status,cmd_output ################################## def json_import(json_file): """ validate and load a json file, return dict""" if not os.path.isfile(json_file): print("\nError: "+os.path.basename(json_file)+ " not found!!\n") sys.exit(1) with open(json_file) as js: try: json_data = json.load(js,object_pairs_hook=OrderedDict) except: print("\nError: "+os.path.basename(json_file)+ " is not a valid json file!!\n") sys.exit(1) return json_data ################################## class json_info(object): def __init__(self,name): if type(name) is not str: print("\nError: "+str(name)+ " must be of type 'str'!!\n") sys.exit(1) ## namey things self.name = name self.rel_path = os.path.dirname(name) self.full_path_name = os.path.abspath(name) self.full_path = os.path.dirname(self.full_path_name) self.full_path_prefix = os.path.splitext(self.full_path_name)[0] self.file_name = os.path.basename(name) self.prefix = os.path.splitext(self.file_name)[0] self.ext = os.path.splitext(self.file_name)[1] ## read in and get list of fields self.dict = json_import(name) self.fields = self.dict.keys() ## some useful fields if "EchoTime" in self.fields: self.te_sec = self.dict["EchoTime"] self.te = self.te_sec * 1000 else: self.te_sec = None ; self.te = None if "RepetitionTime" in self.fields: self.tr = self.dict["RepetitionTime"] else: self.tr = "" if "SliceTiming" in self.fields: self.slice_list = self.dict["SliceTiming"] self.slice_str = ' '.join(map(str,self.slice_list)) else: self.slice_list = None ; self.slice_str = None ## find matching nifti and return afni_name object if os.path.isfile(self.full_path_prefix+".nii.gz"): self.nii = afni_base.afni_name(self.full_path_prefix+".nii.gz") elif os.path.isfile(self.full_path_prefix+".nii"): self.nii = afni_base.afni_name(self.full_path_prefix+".nii") else: self.nii = afni_base.afni_name("None") return def field(self,field_in): """ check and return field_in in a json_info.dict""" if field_in not in self.dict: return None else: return self.dict[field_in] ############################################################## ## graveyard ## run some command or give error # def exec_or_error(cmd_str,error_msg="ERROR!!!"): # """Execute subprocess.Popen(cmd_str,stdout=subprocess.PIPE,shell=True) # Return status and shell output. # On non 0 status print error_msg and exit. # """ # print("") # print(cmd_str) # sys.stdout.flush() # p = subprocess.Popen(cmd_str,stdout=subprocess.PIPE,shell=True) # cmd_output = p.communicate()[0] # print("") # if p.returncode != 0: # print("\n"+error_msg+"\n\n"+cmd_output) # sys.exit(1) # return p.returncode,cmd_output