def test(opt): os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str Dataset = dataset_factory[opt.dataset] opt = Opts().update_dataset_info_and_set_heads(opt, Dataset) print(opt) Logger(opt) Detector = detector_factory[opt.task] split = 'val' if not opt.trainval else 'test' dataset = Dataset(opt, split) detector = Detector(opt) results = {} num_iters = len(dataset) bar = Bar('{}'.format(opt.exp_id), max=num_iters) time_stats = ['tot', 'load', 'pre', 'net', 'dec', 'post', 'merge'] avg_time_stats = {t: AverageMeter() for t in time_stats} for ind in range(num_iters): img_id = dataset.images[ind] img_info = dataset.coco.loadImgs(ids=[img_id])[0] img_path = os.path.join(dataset.img_dir, img_info['file_name']) if opt.task == 'ddd': ret = detector.run(img_path, img_info['calib']) else: ret = detector.run(img_path) results[img_id] = ret['results'] Bar.suffix = '[{0}/{1}]|Tot: {total:} |ETA: {eta:} '.format( ind, num_iters, total=bar.elapsed_td, eta=bar.eta_td) for t in avg_time_stats: avg_time_stats[t].update(ret[t]) Bar.suffix = Bar.suffix + '|{} {:.3f} '.format( t, avg_time_stats[t].avg) bar.next() bar.finish() dataset.run_eval(results, opt.save_dir)
def prefetch_test(opt): os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str Dataset = dataset_factory[opt.dataset] opt = Opts().update_dataset_info_and_set_heads(opt, Dataset) print(opt) Logger(opt) Detector = detector_factory[opt.task] split = 'val' if not opt.trainval else 'test' dataset = Dataset(opt, split) detector = Detector(opt) data_loader = torch.utils.data.DataLoader(PrefetchDataset( opt, dataset, detector.pre_process), batch_size=1, shuffle=False, num_workers=1, pin_memory=True) results = {} num_iters = len(dataset) bar = Bar('{}'.format(opt.exp_id), max=num_iters) time_stats = ['tot', 'load', 'pre', 'net', 'dec', 'post', 'merge'] avg_time_stats = {t: AverageMeter() for t in time_stats} for ind, (img_id, pre_processed_images) in enumerate(data_loader): ret = detector.run(pre_processed_images) results[img_id.numpy().astype(np.int32)[0]] = ret['results'] Bar.suffix = '[{0}/{1}]|Tot: {total:} |ETA: {eta:} '.format( ind, num_iters, total=bar.elapsed_td, eta=bar.eta_td) for t in avg_time_stats: avg_time_stats[t].update(ret[t]) Bar.suffix = Bar.suffix + '|{} {tm.val:.3f}s ({tm.avg:.3f}s) '.format( t, tm=avg_time_stats[t]) bar.next() bar.finish() dataset.run_eval(results, opt.save_dir)
import cv2 import torch from tqdm import tqdm from opts import Opts from utils.utils import test_time_aug, make_dir, img_predict def predict(): with tqdm(total=args.n_test, desc=f'Predict', unit='img') as p_bar: for index, i in enumerate(os.listdir(args.dir_test)): save_path = os.path.join(args.dir_result, i) image = cv2.imread(os.path.join(args.dir_test, i)) img_predict(args, image, save_path=save_path) p_bar.update(1) if __name__ == '__main__': args = Opts().init() args.dir_test = os.path.join(args.dir_data, 'test') args.n_test = len(os.listdir(args.dir_test)) args.net.load_state_dict( torch.load( os.path.join(args.dir_log, f'{args.dataset}_{args.arch}_{args.exp_id}.pth'), map_location=args.device ) ) if args.tta: args.net = test_time_aug(args.net, merge_mode='mean') make_dir(dir_path=args.dir_result) predict()
print('Plotting Calibration..') experiments.plot_defer_simulation(X, y, config) elif config.exp_name == 'toy_regression': print('Toy regression ..') experiments.plot_toy_regression(config) elif config.exp_name == 'clusterwise_ood': print('Plotting OOD..') experiments.plot_ood(X, y, config) elif config.exp_name == 'kl_mode': print('Plotting KL..') experiments.plot_kl(X, y, config) elif config.exp_name == 'show_summary': print('Showing..') experiments.show_model_summary(X, y, config) elif config.exp_name == 'empirical_rule_test': print('Emprical rule tests..') experiments.empirical_rule_test(X, y, config) if __name__ == '__main__': opts = Opts() config = opts.parse() config.verbose = (int)(config.verbose) main(config) # python main.py train --datasets_dir datasets --dataset boston --model_dir boston_anc_models_comsplit_10folds --n_folds 3 --build_model anc_ens --verbose 1
def main(): # Parse the options opts = Opts().parse() opts.device = torch.device(f'cuda:{opts.gpu[0]}') print(opts.expID, opts.task) # Record the start time time_start = time.time() # TODO: select the dataset by the options # Set up dataset train_loader_unit = PENN_CROP(opts, 'train') train_loader = tud.DataLoader(train_loader_unit, batch_size=opts.trainBatch, shuffle=False, num_workers=int(opts.num_workers)) val_loader = tud.DataLoader(PENN_CROP(opts, 'val'), batch_size=1, shuffle=False, num_workers=int(opts.num_workers)) # Read number of joints(dim of output) from dataset opts.nJoints = train_loader_unit.part.shape[1] # Create the Model, Optimizer and Criterion if opts.loadModel == 'none': model = Hourglass2DPrediction(opts).cuda(device=opts.device) else: model = torch.load(opts.loadModel).cuda(device=opts.device) # Set the Criterion and Optimizer criterion = torch.nn.MSELoss(reduce=False).cuda(device=opts.device) # opts.nOutput = len(model.outnode.children) optimizer = torch.optim.RMSprop(model.parameters(), opts.LR, alpha=opts.alpha, eps=opts.epsilon, weight_decay=opts.weightDecay, momentum=opts.momentum) # If TEST, just validate # TODO: save the validate results to mat or hdf5 if opts.test: loss_test, pck_test = val(0, opts, val_loader, model, criterion) print(f"test: | loss_test: {loss_test}| PCK_val: {pck_test}\n") ## TODO: save the predictions for the test #sio.savemat(os.path.join(opts.saveDir, 'preds.mat'), mdict = {'preds':preds}) return # NOT TEST, Train and Validate for epoch in range(1, opts.nEpochs + 1): ## Train the model loss_train, pck_train = train(epoch, opts, train_loader, model, criterion, optimizer) ## Show results and elapsed time time_elapsed = time.time() - time_start print( f"epoch: {epoch} | loss_train: {loss_train} | PCK_train: {pck_train} | {time_elapsed//60:.0f}min {time_elapsed%60:.0f}s\n" ) ## Intervals to show eval results if epoch % opts.valIntervals == 0: # TODO: Test the validation part ### Validation loss_val, pck_val = val(epoch, opts, val_loader, model, criterion) print( f"epoch: {epoch} | loss_val: {loss_val}| PCK_val: {pck_val}\n") ### Save the model torch.save(model, os.path.join(opts.save_dir, f"model_{epoch}.pth")) ### TODO: save the preds for the validation #sio.savemat(os.path.join(opts.saveDir, f"preds_{epoch}.mat"), mdict={'preds':preds}) # Use the optimizer to adjust learning rate if epoch % opts.dropLR == 0: lr = adjust_learning_rate(optimizer, epoch, opts.dropLR, opts.LR) print(f"Drop LR to {lr}\n")
def generate_B0ECC_SeqFile(iT, tr, te, Npuls, mg, ms, grt, fA, reps, sliceT, tPre, tPos, tX, tY, tZ, tPlot, tReport, testPRE_POST, rf_offset, dummy, Ndummies): # %% =========================================================================== # %% --- 1 - Instantiation and gradient limits --- system = Opts(max_grad=mg, grad_unit='mT/m', max_slew=ms, slew_unit='T/m/s', rf_ringdown_time=20e-6, rf_dead_time=100e-6, adc_dead_time=10e-6) seq = Sequence(system) # I need to check the manually inputed inverse raster time and the actual value are the same. i_raster_time = 100000 assert 1 / i_raster_time == seq.grad_raster_time, "Manualy inputed inverse raster time does not match the actual value." slice_thickness, slice_gap, TR, TE, rf_offset_z = sliceT, 15e-3, tr, te, 0 posAxxis = [slice_thickness + rf_offset, -slice_thickness - rf_offset] # %% --- 2 - Gradients G = iT G_zero = np.zeros(len(iT[:, 0])) G_pre = np.zeros(math.floor(tPre * i_raster_time)) G_pos = np.zeros(math.floor(tPos * i_raster_time)) # %% --- 3 - Slice Selection # ========= # Create 90 degree slice selection pulse and gradient # ========= # RF90 flip90 = fA * pi / 180 rfx, gxRF, gxr = make_sinc_pulse_channel(channel='x', flip_angle=flip90, duration=3e-3, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4, system=system) rfy, gyRF, gyr = make_sinc_pulse_channel(channel='y', flip_angle=flip90, duration=3e-3, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4, system=system) rfz, gzRF, gzr = make_sinc_pulse(flip_angle=flip90, duration=3e-3, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4, system=system) # %% --- 4 - ADCs / Readouts adc_samples = math.floor(len(G) / 4) * 4 - 1 adc_samples_pre = math.floor(len(G_pre) / 4) * 4 - 2 adc_samples_pos = math.floor(len(G_pos) / 4) * 4 - 100 adc = make_adc(num_samples=adc_samples, duration=adc_samples / i_raster_time, system=system) adc_pre = make_adc(num_samples=adc_samples_pre, duration=adc_samples_pre / i_raster_time, system=system) adc_pos = make_adc(num_samples=adc_samples_pos, duration=adc_samples_pos / i_raster_time, system=system) # %% --- 5 - Spoilers pre_time = 8e-4 n_pre_time = math.ceil(pre_time * i_raster_time) gx_rephz = make_trapezoid(channel='x', area=-gxRF.area / 2, duration=2e-3, system=system) gx_spoil = make_trapezoid(channel='x', area=-gxRF.area / 2, duration=3 * n_pre_time / i_raster_time, system=system) gy_rephz = make_trapezoid(channel='y', area=-gyRF.area / 2, duration=2e-3, system=system) gy_spoil = make_trapezoid(channel='y', area=-gyRF.area / 2, duration=3 * n_pre_time / i_raster_time, system=system) gz_rephz = make_trapezoid(channel='z', area=-gzRF.area / 2, duration=2e-3, system=system) gz_spoil = make_trapezoid(channel='z', area=-gzRF.area / 2, duration=3 * n_pre_time / i_raster_time, system=system) # double area for all second pulses gx_spoil_double = make_trapezoid(channel='x', area=-gxRF.area, duration=3 * n_pre_time / i_raster_time, system=system) gy_spoil_double = make_trapezoid(channel='y', area=-gyRF.area, duration=3 * n_pre_time / i_raster_time, system=system) gz_spoil_double = make_trapezoid(channel='z', area=-gzRF.area, duration=3 * n_pre_time / i_raster_time, system=system) aux_gx = make_arbitrary_grad(channel='x', waveform=np.squeeze(G[:, 0]), system=system) aux_gy = make_arbitrary_grad(channel='y', waveform=np.squeeze(G[:, 0]), system=system) aux_gz = make_arbitrary_grad(channel='y', waveform=np.squeeze(G[:, 0]), system=system) # %% --- 6 - Calculate timing/Delays n_TE = math.ceil(TE * i_raster_time) n_TR = math.ceil(TR * i_raster_time) n_dur_adc_pre = math.ceil(calc_duration(adc_pre) * i_raster_time) n_dur_adc_pos = math.ceil(calc_duration(adc_pos) * i_raster_time) # for x # delay pre ADC n_dur_gx_rephz = math.ceil(calc_duration(gx_rephz) * i_raster_time) n_dur_rfx = math.ceil(calc_duration(rfx) * i_raster_time) n_del_preGRS_x = n_TE - (n_dur_gx_rephz + math.ceil(n_dur_rfx / 2) ) # Time before input in points del_preGRS_x = n_del_preGRS_x / i_raster_time delay_preGRS_x = make_delay(del_preGRS_x) # delay pos ADC n_dur_aux_gx = math.ceil(calc_duration(aux_gx) * i_raster_time) n_dur_gx_spoil = math.ceil(calc_duration(gx_spoil) * i_raster_time) n_delTR_x = n_TR - ( n_dur_gx_rephz + math.ceil(n_dur_rfx / 2) + n_dur_adc_pre + n_dur_aux_gx + n_dur_adc_pos + n_dur_gx_spoil ) # Time after input to the system in points delTR_x = n_delTR_x / i_raster_time delayTR_x = make_delay(delTR_x) # for y # delay pre ADC n_dur_gy_rephz = math.ceil(calc_duration(gy_rephz) * i_raster_time) n_dur_rfy = math.ceil(calc_duration(rfy) * i_raster_time) n_del_preGRS_y = n_TE - (n_dur_gy_rephz + math.ceil(n_dur_rfy / 2) ) # Time before input in points del_preGRS_y = n_del_preGRS_y / i_raster_time delay_preGRS_y = make_delay(del_preGRS_y) # delay pos ADC n_dur_aux_gy = math.ceil(calc_duration(aux_gy) * i_raster_time) n_dur_gy_spoil = math.ceil(calc_duration(gy_spoil) * i_raster_time) n_delTR_y = n_TR - (n_dur_gy_rephz + math.ceil(n_dur_rfy / 2) + n_dur_adc_pre + n_dur_aux_gy + n_dur_adc_pos + n_dur_gy_spoil) delTR_y = n_delTR_y / i_raster_time delayTR_y = make_delay(delTR_y) # for z # delay pre ADC n_dur_gz_rephz = math.ceil(calc_duration(gz_rephz) * i_raster_time) n_dur_rfz = math.ceil(calc_duration(rfz) * i_raster_time) n_del_preGRS_z = n_TE - (n_dur_gz_rephz + math.ceil(n_dur_rfz / 2) ) # Time before input in points del_preGRS_z = n_del_preGRS_z / i_raster_time delay_preGRS_z = make_delay(del_preGRS_z) # delay pos ADC n_dur_aux_gz = math.ceil(calc_duration(aux_gz) * i_raster_time) n_dur_gz_spoil = math.ceil(calc_duration(gx_spoil) * i_raster_time) n_delTR_z = n_TR - (n_dur_gz_rephz + math.ceil(n_dur_rfz / 2) + n_dur_adc_pre + n_dur_aux_gz + n_dur_adc_pos + n_dur_gz_spoil) delTR_z = n_delTR_z / i_raster_time delayTR_z = make_delay(delTR_z) # %% --- 7 - Define sequence for measuring k_trajectory - blocks/Readouts if dummy: for nd in range(Ndummies): # for x and y rf pulse freq_offset_gx = gxRF.amplitude * posAxxis[0] rfx.freq_offset = freq_offset_gx freq_offset_gy = gyRF.amplitude * posAxxis[0] rfy.freq_offset = freq_offset_gy # RF90 seq.add_block(rfx, gxRF) seq.add_block(gx_rephz) # Delay for spiral seq.add_block(delay_preGRS_x) # Read k-space - Imaging Gradient waveforms gx_zero = make_arbitrary_grad(channel='x', waveform=np.squeeze(G_zero), system=system) seq.add_block(adc, gx_zero) # Gradients Spoils seq.add_block(gx_spoil) # Delay to TR seq.add_block(delayTR_x) n_x = 0 if tX: for ns in range(Npuls): for r in range(reps): for s in range(2): # for position of axis for a in range(2): # for positive or negative gradient n_x = n_x + 1 # for x rf pulse freq_offset_gx = gxRF.amplitude * posAxxis[s] rfx.freq_offset = freq_offset_gx # RF90 seq.add_block(rfx, gxRF) seq.add_block(gx_rephz) # Delay for spiral seq.add_block(delay_preGRS_x) # Read - pre GIRF if testPRE_POST: gx_pre = make_arbitrary_grad( channel='x', waveform=np.squeeze(G_pre), system=system) seq.add_block(adc_pre, gx_pre) # Read k-space - Imaging Gradient waveforms if a == 1: # %% --- for x-axis negative gradient --- %% # gx = make_arbitrary_grad(channel='x', waveform=np.squeeze( G[:, ns] * -1), system=system) else: # %% --- for x-axis positive gradient --- %% # gx = make_arbitrary_grad(channel='x', waveform=np.squeeze( G[:, ns]), system=system) seq.add_block(adc, gx) # Read - pos GIRF if testPRE_POST: gx_pos = make_arbitrary_grad( channel='x', waveform=np.squeeze(G_pos), system=system) seq.add_block(adc_pos, gx_pos) # Gradients Spoils if (n_x % 2) == 0: # seq.add_block(gx_spoil,gy_spoil,gz_spoil) seq.add_block(gx_spoil_double) # seq.add_block(gy_spoil_double) else: # seq.add_block(gx_spoil,gy_spoil,gz_spoil) seq.add_block(gx_spoil) # seq.add_block(gy_spoil) # Delay to TR seq.add_block(delayTR_x) n_y = 0 if tY: for ns in range(Npuls): for r in range(reps): for s in range(2): for a in range(2): n_y = n_y + 1 # for x rf pulse freq_offset_gy = gyRF.amplitude * posAxxis[s] rfy.freq_offset = freq_offset_gy # RF90 seq.add_block(rfy, gyRF) seq.add_block(gy_rephz) # Delay for spiral seq.add_block(delay_preGRS_y) # Read - pre GIRF if testPRE_POST: gy_pre = make_arbitrary_grad( channel='y', waveform=np.squeeze(G_pre), system=system) seq.add_block(adc_pre, gy_pre) # Read k-space - Imaging Gradient waveforms if a == 1: # %% --- for y-axis negative gradient --- %% # gy = make_arbitrary_grad(channel='y', waveform=np.squeeze( G[:, ns] * -1), system=system) else: # %% --- for y-axis positive gradient --- %% # gy = make_arbitrary_grad(channel='y', waveform=np.squeeze( G[:, ns]), system=system) seq.add_block(adc, gy) # Read - pos GIRF if testPRE_POST: gy_pos = make_arbitrary_grad( channel='y', waveform=np.squeeze(G_pos), system=system) seq.add_block(adc_pos, gy_pos) # Gradients Spoils if (n_y % 2) == 0: # seq.add_block(gx_spoil,gy_spoil,gz_spoil) seq.add_block(gy_spoil_double) # seq.add_block(gx_spoil_double) else: # seq.add_block(gx_spoil,gy_spoil,gz_spoil) seq.add_block(gy_spoil) # seq.add_block(gx_spoil) # Delay to TR seq.add_block(delayTR_y) if tZ: for ns in range(Npuls): for r in range(reps): for s in range(2): for a in range(2): # for x rf pulse freq_offset_gz = gzRF.amplitude * posAxxis[s] rfz.freq_offset = freq_offset_gz # RF90 seq.add_block(rfz, gz_rephz) # Delay for spiral seq.add_block(delay_preGRS_z) # Read - pre GIRF if testPRE_POST: gz_pre = make_arbitrary_grad( channel='z', waveform=np.squeeze(G_pre), system=system) seq.add_block(adc_pre, gz_pre) # Read k-space - Imaging Gradient waveforms if a == 1: # %% --- for y-axis negative gradient --- %% # gz = make_arbitrary_grad(channel='z', waveform=np.squeeze( G[:, ns] * -1), system=system) else: # %% --- for y-axis positive gradient --- %% # gz = make_arbitrary_grad(channel='z', waveform=np.squeeze( G[:, ns]), system=system) seq.add_block(adc, gz) # Read - pos GIRF if testPRE_POST: gz_pos = make_arbitrary_grad( channel='z', waveform=np.squeeze(G_pos), system=system) seq.add_block(adc_pos, gz_pos) # Gradients Spoils seq.add_block(gx_spoil, gy_spoil, gz_spoil) # seq.add_block(gz_spoil) # Delay to TR seq.add_block(delayTR_z) # %% --- 8 - Plot ADCs, GX, GY, GZ, RFpulse, RFphase # # plt.figure() if tPlot: seq.plot() if tReport: print(seq.test_report()) seq.check_timing() return seq
def main(opt): torch.manual_seed(opt.seed) torch.backends.cudnn.benchmark = not opt.not_cuda_benchmark and not opt.test Dataset = get_dataset(opt.dataset, opt.task) val_dataset = Dataset(opt, 'val') opt = Opts().update_dataset_info_and_set_heads(opt, val_dataset) print(opt) logger = Logger(opt) os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str opt.device = torch.device('cuda' if opt.gpus[0] >= 0 else 'cpu') print('Creating model...') model = create_model(opt.arch, opt.heads, opt.head_conv) optimizer = torch.optim.Adam(model.parameters(), opt.lr) start_epoch = 0 if opt.load_model != '': model, optimizer, start_epoch = load_model( model, opt.load_model, optimizer, opt.resume, opt.lr, opt.lr_step) print("Model:") print(model) print("Total number of parameters: {}".format(count_parameters(model))) print("Trainable parameters: {}".format(count_parameters(model, trainable=True))) Trainer = train_factory[opt.task] trainer = Trainer(opt, model, optimizer) trainer.set_device(opt.gpus, opt.chunk_sizes, opt.device) print('Setting up data...') val_loader = torch.utils.data.DataLoader( val_dataset, batch_size=1, shuffle=False, num_workers=1, pin_memory=True ) if opt.test: _, preds = trainer.val(0, val_loader) val_loader.dataset.run_eval(preds, opt.save_dir) print("{} images failed!".format(len(val_loader.dataset.failed_images))) print(val_loader.dataset.failed_images) return train_loader = torch.utils.data.DataLoader( Dataset(opt, 'train'), batch_size=opt.batch_size, shuffle=True, num_workers=opt.num_workers, pin_memory=True, drop_last=True ) # Report failed images failed_images = list(train_loader.dataset.failed_images | val_loader.dataset.failed_images) if len(failed_images): print("{} images failed!".format(len(failed_images))) dump_path = os.path.join(opt.save_dir, 'failed_images.json') with open(dump_path, 'w') as f: json.dump(failed_images, f, sort_keys=True, indent=4, separators=(',', ': ')) print("Failed image paths saved in: {}".format(dump_path)) print('Starting training...') best = 1e10 for epoch in range(start_epoch + 1, opt.num_epochs + 1): mark = epoch if opt.save_all else 'last' log_dict_train, _ = trainer.train(epoch, train_loader) logger.write('epoch: {} |'.format(epoch)) for k, v in log_dict_train.items(): logger.scalar_summary('train_{}'.format(k), v, epoch) logger.write('{} {:8f} | '.format(k, v)) if opt.val_intervals > 0 and epoch % opt.val_intervals == 0: save_model(os.path.join(opt.save_dir, 'model_{}.pth'.format(mark)), epoch, model, optimizer) with torch.no_grad(): log_dict_val, preds = trainer.val(epoch, val_loader) for k, v in log_dict_val.items(): logger.scalar_summary('val_{}'.format(k), v, epoch) logger.write('{} {:8f} | '.format(k, v)) if log_dict_val[opt.metric] < best: best = log_dict_val[opt.metric] save_model(os.path.join(opt.save_dir, 'model_best.pth'), epoch, model) else: save_model(os.path.join(opt.save_dir, 'model_last.pth'), epoch, model, optimizer) logger.write('\n') if epoch in opt.lr_step: save_model(os.path.join(opt.save_dir, 'model_{}.pth'.format(epoch)), epoch, model, optimizer) lr = opt.lr * (0.1 ** (opt.lr_step.index(epoch) + 1)) print('Drop LR to', lr) for param_group in optimizer.param_groups: param_group['lr'] = lr logger.close()
logger.write('{} {:8f} | '.format(k, v)) if opt.val_intervals > 0 and epoch % opt.val_intervals == 0: save_model(os.path.join(opt.save_dir, 'model_{}.pth'.format(mark)), epoch, model, optimizer) with torch.no_grad(): log_dict_val, preds = trainer.val(epoch, val_loader) for k, v in log_dict_val.items(): logger.scalar_summary('val_{}'.format(k), v, epoch) logger.write('{} {:8f} | '.format(k, v)) if log_dict_val[opt.metric] < best: best = log_dict_val[opt.metric] save_model(os.path.join(opt.save_dir, 'model_best.pth'), epoch, model) else: save_model(os.path.join(opt.save_dir, 'model_last.pth'), epoch, model, optimizer) logger.write('\n') if epoch in opt.lr_step: save_model(os.path.join(opt.save_dir, 'model_{}.pth'.format(epoch)), epoch, model, optimizer) lr = opt.lr * (0.1 ** (opt.lr_step.index(epoch) + 1)) print('Drop LR to', lr) for param_group in optimizer.param_groups: param_group['lr'] = lr logger.close() if __name__ == '__main__': opt = Opts().parse() main(opt)
def main(): # Parse the options from parameters opts = Opts().parse() ## For PyTorch 0.4.1, cuda(device) opts.device = torch.device(f'cuda:{opts.gpu[0]}') print(opts.expID, opts.task, os.path.dirname(os.path.realpath(__file__))) # Load the trained model test if opts.loadModel != 'none': model_path = os.path.join(opts.root_dir, opts.loadModel) model = torch.load(model_path).cuda(device=opts.device) model.eval() else: print('ERROR: No model is loaded!') return # Read the input image, pass input to gpu if opts.img == 'None': val_dataset = PENN_CROP(opts, 'val') val_loader = tud.DataLoader(val_dataset, batch_size=1, shuffle=False, num_workers=int(opts.num_workers)) opts.nJoints = val_dataset.nJoints opts.skeleton = val_dataset.skeleton for i, gt in enumerate(val_loader): # Test Visualizer, Input and get_preds if i == 0: input, label = gt['input'], gt['label'] gtpts, center, scale, proj = gt['gtpts'], gt['center'], gt[ 'scale'], gt['proj'] input_var = input[:, 0, ].float().cuda(device=opts.device, non_blocking=True) # output = label output = model(input_var) # Test Loss, Err and Acc(PCK) Loss, Err, Acc = AverageMeter(), AverageMeter(), AverageMeter() ref = get_ref(opts.dataset, scale) for j in range(opts.preSeqLen): pred = get_preds(output[:, j, ].cpu().float()) pred = original_coordinate(pred, center[:, ], scale, opts.outputRes) err, ne = error(pred, gtpts[:, j, ], ref) acc, na = accuracy(pred, gtpts[:, j, ], ref) # assert ne == na, "ne must be the same as na" Err.update(err) Acc.update(acc) print(j, f"{Err.val:.6f}", Acc.val) print('all', f"{Err.avg:.6f}", Acc.avg) # Visualizer Object ## Initialize v = Visualizer(opts.nJoints, opts.skeleton, opts.outputRes) # ## Add input image # v.add_img(input[0,0,].transpose(2, 0).numpy().astype(np.uint8)) # ## Get the predicted joints # predJoints = get_preds(output[:, 0, ]) # # ## Add joints and skeleton to the figure # v.add_2d_joints_skeleton(predJoints, (0, 0, 255)) # Transform heatmap to show hm_img = output[0, 0, ].cpu().detach().numpy() v.add_hm(hm_img) ## Show image v.show_img(pause=True) break else: print('NOT ready for the raw input outside the dataset') img = cv2.imread(opts.img) input = torch.from_numpy(img.tramspose(2, 0, 1)).float() / 256. input = input.view(1, input.size(0), input.size(1), input.size(2)) input_var = torch.autograd.variable(input).float().cuda( device=opts.device) output = model(input_var) predJoints = get_preds(output[-2].data.cpu().numpy())[0] * 4
def generate_SeqFile_Spiral(gx, gy, tr, n_shots, mg, ms, fA, n_slices, reps, st, tPlot, tReport, rf_offset=0): #%% =========================================================================== # --- 1 - Instantiation and gradient limits --- system = Opts(max_grad=mg, grad_unit='mT/m', max_slew=ms, slew_unit='T/m/s', rf_ringdown_time=20e-6, rf_dead_time=100e-6, adc_dead_time=10e-6) seq = Sequence(system) # I need to check the manually inputed inverse raster time and the actual value are the same. i_raster_time = 100000 assert 1 / i_raster_time == seq.grad_raster_time, "Manualy inputed inverse raster time does not match the actual value." slice_thickness, slice_gap, TE, TR = st, 15e-3, 5e-3, tr delta_z = n_slices * slice_thickness z = np.linspace((-delta_z / 2), (delta_z / 2), n_slices) + rf_offset #%% --- 2 - Gradients # scl = 1.05 # gx = gx/(scl*np.max(gx)/(max_grad*42576000e-3)); # gy = gy/(scl*np.max(gy)/(max_grad*42576000e-3)); G = gx + 1J * gy #%% --- 3 - Slice Selection # ========= # Create 90 degree slice selection pulse and gradient # ========= # RF90 flip90 = fA * pi / 180 rf, gz, gzr = make_sinc_pulse(flip_angle=flip90, duration=3e-3, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4, system=system) # RF180 #%% --- 4 - ADCs / Readouts adc_samples = math.floor(len(G) / 4) * 4 - 4 adc = make_adc(num_samples=adc_samples, duration=adc_samples / i_raster_time, system=system) #%% --- 5 - Spoilers pre_time = 8e-4 n_pre_time = math.ceil(pre_time * i_raster_time) gz_rephz = make_trapezoid(channel='z', area=-gz.area / 2, duration=1e-3, system=system) gz_spoil = make_trapezoid(channel='z', area=-gz.area / 2, duration=3 * n_pre_time / i_raster_time, system=system) aux_gx = make_arbitrary_grad(channel='x', waveform=np.squeeze(np.real(G[:, 0])), system=system) # Make the spiral in Gx and Gy finish in zero - I use pre_time because I know for sure it's long enough. # Furthermore, this is after readout and TR is supposed to be long. spoil_time = [0, calc_duration(gz_spoil)] gxAmplitud_Spoil = [np.real(G[-1][0]), 0] gyAmplitud_Spoil = [np.imag(G[-1][0]), 0] gx_spoil = make_extended_trapezoid(channel='x', times=spoil_time, amplitudes=gxAmplitud_Spoil, system=system) gy_spoil = make_extended_trapezoid(channel='y', times=spoil_time, amplitudes=gyAmplitud_Spoil, system=system) # # ========= # # Prephase and Rephase # # ========= # phase_areas = (np.arange(Ny) - (Ny / 2)) * delta_k # kwargs_for_gy_pre = {"channel": 'y', "system": system, "area": phase_areas[-1], "duration": 2e-3} # gy_pre = maketrapezoid(kwargs_for_gy_pre) # # kwargs_for_gxpre = {"channel": 'x', "system": system, "area": -gx.area / 2, "duration": 2e-3} # gx_pre = maketrapezoid(kwargs_for_gxpre) # # kwargs_for_gz_reph = {"channel": 'z', "system": system, "area": -gz.area / 2, "duration": 2e-3} # gz_reph = maketrapezoid(kwargs_for_gz_reph) #%% --- 6 - Calculate timing/Delays n_TE = math.ceil(TE * i_raster_time) n_dur_gz_rephz = math.ceil(calc_duration(gz_rephz) * i_raster_time) n_dur_rf = math.ceil(calc_duration(rf) * i_raster_time) n_del_preGRS = n_TE - (n_dur_gz_rephz + math.ceil(n_dur_rf / 2) ) # Time before input in points del_preGRS = n_del_preGRS / i_raster_time delay_preGRS = make_delay(del_preGRS) n_TR = math.ceil(TR * i_raster_time) n_dur_aux_gx = math.ceil(calc_duration(aux_gx) * i_raster_time) n_dur_gz_spoil = math.ceil(calc_duration(gz_spoil) * i_raster_time) n_delTR = n_TR - (n_dur_gz_rephz + n_dur_rf - n_dur_aux_gx - n_dur_gz_spoil ) # Time after input to the system in points delTR = n_delTR / i_raster_time delayTR = make_delay(delTR) #%% --- 7 - Define sequence blocks/Readouts + Create '.seq' file for r in range(reps): for s in range(n_slices): for ns in range(n_shots): freq_offset = gz.amplitude * z[s] rf.freq_offset = freq_offset # RF90 seq.add_block(rf, gz) seq.add_block(gz_rephz) # Delay for spiral seq.add_block(delay_preGRS) # if (r % 2 == 0): # Read k-space - Imaging Gradient waveforms gx = make_arbitrary_grad(channel='x', waveform=np.squeeze(np.real(G[:, ns])), system=system) gy = make_arbitrary_grad(channel='y', waveform=np.squeeze(np.imag(G[:, ns])), system=system) seq.add_block(gx, gy, adc) # Gradients Spoils seq.add_block(gz_spoil, gx_spoil, gy_spoil) # seq.add_block(gz_spoil) # else: # to allow measure phase with no gradient # # Read k-space - Imaging Gradient waveforms # seq.add_block(adc) # # # Gradients Spoils # seq.add_block(gz_spoil) # Delay to TR seq.add_block(delayTR) # %% --- 8 - Plot ADCs, GX, GY, GZ, RFpulse, RFphase # # plt.figure() if tPlot: seq.plot() if tReport: print(seq.test_report()) seq.check_timing() return seq
def generate_SeqFile_SpiralDiffusion(gx, gy, tr, n_shots, mg, ms, fA, n_slices, reps, st, tPlot, tReport, b_values, n_dirs, fov, Nx): #%% --- 1 - Create new Sequence Object + Parameters seq = Sequence() # ========= # Parameters # ========= i_raster_time = 100000 assert 1 / i_raster_time == seq.grad_raster_time, "Manualy inputed inverse raster time does not match the actual value." # ========= # Code parameters # ========= fatsat_enable = 0 # Fat saturation kplot = 0 # ========= # Acquisition Parameters # ========= TR = tr # Spin-Echo parameters - TR in [s] n_TR = math.ceil( TR * i_raster_time) # Spin-Echo parameters - number of points TR bvalue = b_values # b-value [s/mm2] nbvals = np.shape(bvalue)[0] # b-value parameters ndirs = n_dirs # b-value parameters Ny = Nx slice_thickness = st # Acquisition Parameters in [m] Nshots = n_shots # ========= # Gradient Scaling # ========= gscl = np.zeros(nbvals + 1) gscl[1:] = np.sqrt(bvalue / np.max(bvalue)) gdir, nb0s = difunc.get_dirs(ndirs) # ========= # Create system # ========= system = Opts(max_grad=mg, grad_unit='mT/m', max_slew=ms, slew_unit='T/m/s', rf_ringdown_time=20e-6, rf_dead_time=100e-6, adc_dead_time=10e-6) #%% --- 2 - Fat saturation if fatsat_enable: fatsat_str = "_fatsat" b0 = 1.494 sat_ppm = -3.45 sat_freq = sat_ppm * 1e-6 * b0 * system.gamma rf_fs, _, _ = make_gauss_pulse(flip_angle=110 * math.pi / 180, system=system, duration=8e-3, bandwidth=abs(sat_freq), freq_offset=sat_freq) gz_fs = make_trapezoid(channel='z', system=system, delay=calc_duration(rf_fs), area=1 / 1e-4) else: fatsat_str = "" #%% --- 3 - Slice Selection # ========= # Create 90 degree slice selection pulse and gradient # ========= flip90 = fA * pi / 180 rf, gz, _ = make_sinc_pulse(flip_angle=flip90, system=system, duration=3e-3, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4) # ========= # Refocusing pulse with spoiling gradients # ========= rf180, gz180, _ = make_sinc_pulse(flip_angle=math.pi, system=system, duration=5e-3, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4) rf180.phase_offset = math.pi / 2 gz_spoil = make_trapezoid(channel='z', system=system, area=6 / slice_thickness, duration=3e-3) #%% --- 4 - Gradients # ========= # Spiral trajectory # ========= G = gx + 1J * gy #%% --- 5 - ADCs / Readouts delta_k = 1 / fov adc_samples = math.floor( len(G) / 4 ) * 4 - 2 # Apparently, on Siemens the number of samples needs to be divisible by 4... adc = make_adc(num_samples=adc_samples, system=system, duration=adc_samples / i_raster_time) # ========= # Pre-phasing gradients # ========= pre_time = 1e-3 n_pre_time = math.ceil(pre_time * i_raster_time) gz_reph = make_trapezoid(channel='z', system=system, area=-gz.area / 2, duration=pre_time) #%% --- 6 - Obtain TE and diffusion-weighting gradient waveform # For S&T monopolar waveforms # From an initial TE, check we satisfy all constraints -> otherwise increase TE. # Once all constraints are okay -> check b-value, if it is lower than the target one -> increase TE # Looks time-inefficient but it is fast enough to make it user-friendly. # TODO: Re-scale the waveform to the exact b-value because increasing the TE might produce slightly higher ones. # Calculate some times constant throughout the process # We need to compute the exact time sequence. For the normal SE-MONO-EPI sequence micro second differences # are not important, however, if we wanna import external gradients the allocated time for them needs to # be the same, and thus exact timing is mandatory. With this in mind, we establish the following rounding rules: # Duration of RFs + spoiling, and EPI time to the center of the k-space is always math.ceil(). # The time(gy) refers to the number of blips, thus we substract 0.5 since the number of lines is always even. # The time(gx) refers to the time needed to read each line of the k-space. Thus, if Ny is even, it would take half of the lines plus another half. n_duration_center = 0 # The spiral starts right in 0 -- or ADC_dead_time?? rf_center_with_delay = rf.delay + calc_rf_center(rf)[0] n_rf90r = math.ceil((calc_duration(gz) - rf_center_with_delay + pre_time) / seq.grad_raster_time) n_rf180r = math.ceil((calc_duration(rf180) + 2 * calc_duration(gz_spoil)) / 2 / seq.grad_raster_time) n_rf180l = math.floor( (calc_duration(rf180) + 2 * calc_duration(gz_spoil)) / 2 / seq.grad_raster_time) # ========= # Find minimum TE considering the readout times. # ========= n_TE = math.ceil(20e-3 / seq.grad_raster_time) n_delay_te1 = -1 while n_delay_te1 <= 0: n_TE = n_TE + 2 n_tINV = math.floor(n_TE / 2) n_delay_te1 = n_tINV - n_rf90r - n_rf180l # ========= # Find minimum TE for the target b-value # ========= bvalue_tmp = 0 while bvalue_tmp < np.max(bvalue): n_TE = n_TE + 2 n_tINV = math.floor(n_TE / 2) n_delay_te1 = n_tINV - n_rf90r - n_rf180l delay_te1 = n_delay_te1 / i_raster_time n_delay_te2 = n_tINV - n_rf180r - n_duration_center delay_te2 = n_delay_te2 / i_raster_time # Waveform Ramp time n_gdiff_rt = math.ceil(system.max_grad / system.max_slew / seq.grad_raster_time) # Select the shortest available time n_gdiff_delta = min(n_delay_te1, n_delay_te2) n_gdiff_Delta = n_delay_te1 + 2 * math.ceil( calc_duration(gz_spoil) / seq.grad_raster_time) + math.ceil( calc_duration(gz180) / seq.grad_raster_time) gdiff = make_trapezoid(channel='x', system=system, amplitude=system.max_grad, duration=n_gdiff_delta / i_raster_time) # delta only corresponds to the rectangle. n_gdiff_delta = n_gdiff_delta - 2 * n_gdiff_rt bv = difunc.calc_bval(system.max_grad, n_gdiff_delta / i_raster_time, n_gdiff_Delta / i_raster_time, n_gdiff_rt / i_raster_time) bvalue_tmp = bv * 1e-6 # ========= # Show final TE and b-values: # ========= print("TE:", round(n_TE / i_raster_time * 1e3, 2), "ms") for bv in range(1, nbvals + 1): print( round( difunc.calc_bval(system.max_grad * gscl[bv], n_gdiff_delta / i_raster_time, n_gdiff_Delta / i_raster_time, n_gdiff_rt / i_raster_time) * 1e-6, 2), "s/mm2") TE = n_TE / i_raster_time TR = n_TR / i_raster_time #%% --- 7 - Crusher gradients gx_crush = make_trapezoid(channel='x', area=2 * Nx * delta_k, system=system) gz_crush = make_trapezoid(channel='z', area=4 / slice_thickness, system=system) # TR delay - Takes everything into account # Distance between the center of the RF90s must be TR # The n_pre_time here is the time used to drive the Gx, and Gy spiral gradients to zero. n_spiral_time = adc_samples n_tr_per_slice = math.ceil(TR / n_slices * i_raster_time) if fatsat_enable: n_tr_delay = n_tr_per_slice - (n_TE - n_duration_center + n_spiral_time) \ - math.ceil(rf_center_with_delay * i_raster_time) \ - n_pre_time \ - math.ceil(calc_duration(gx_crush, gz_crush) * i_raster_time) \ - math.ceil(calc_duration(rf_fs, gz_fs) * i_raster_time) else: n_tr_delay = n_tr_per_slice - (n_TE - n_duration_center + n_spiral_time) \ - math.ceil(rf_center_with_delay * i_raster_time) \ - n_pre_time \ - math.ceil(calc_duration(gx_crush, gz_crush) * i_raster_time) tr_delay = n_tr_delay / i_raster_time #%% --- 8 - Checks # ========= # Check TR delay time # ========= assert n_tr_delay > 0, "Such parameter configuration needs longer TR." # ========= # Delay time, # ========= # Time between the gradient and the RF180. This time might be zero some times, although it is not normal. if n_delay_te1 > n_delay_te2: n_gap_te1 = n_delay_te1 - n_delay_te2 gap_te1 = n_gap_te1 / i_raster_time gap_te2 = 0 else: n_gap_te2 = n_delay_te2 - n_delay_te1 gap_te2 = n_gap_te2 / i_raster_time gap_te1 = 0 #%% --- 9 - b-zero acquisition for r in range(reps): for d in range(nb0s): for nshot in range(Nshots): for s in range(n_slices): # Fat saturation if fatsat_enable: seq.add_block(rf_fs, gz_fs) # RF90 rf.freq_offset = gz.amplitude * slice_thickness * ( s - (n_slices - 1) / 2) seq.add_block(rf, gz) seq.add_block(gz_reph) # Delay for RF180 seq.add_block(make_delay(delay_te1)) # RF180 seq.add_block(gz_spoil) rf180.freq_offset = gz180.amplitude * slice_thickness * ( s - (n_slices - 1) / 2) seq.add_block(rf180, gz180) seq.add_block(gz_spoil) # Delay for spiral seq.add_block(make_delay(delay_te2)) # Read k-space # Imaging Gradient waveforms gx = make_arbitrary_grad(channel='x', waveform=np.squeeze( G[:, nshot].real), system=system) gy = make_arbitrary_grad(channel='y', waveform=np.squeeze( G[:, nshot].imag), system=system) seq.add_block(gx, gy, adc) # Make the spiral finish in zero - I use pre_time because I know for sure it's long enough. # Furthermore, this is after readout and TR is supposed to be long. amp_x = [G[:, nshot].real[-1], 0] amp_y = [G[:, nshot].imag[-1], 0] gx_to_zero = make_extended_trapezoid(channel='x', amplitudes=amp_x, times=[0, pre_time], system=system) gy_to_zero = make_extended_trapezoid(channel='y', amplitudes=amp_y, times=[0, pre_time], system=system) seq.add_block(gx_to_zero, gy_to_zero) seq.add_block(gx_crush, gz_crush) # Wait TR if tr_delay > 0: seq.add_block(make_delay(tr_delay)) #%% --- 9 - DWI acquisition for r in range(reps): for bv in range(1, nbvals + 1): for d in range(ndirs): for nshot in range(Nshots): for s in range(n_slices): # Fat saturation if fatsat_enable: seq.add_block(rf_fs, gz_fs) # RF90 rf.freq_offset = gz.amplitude * slice_thickness * ( s - (n_slices - 1) / 2) seq.add_block(rf, gz) seq.add_block(gz_reph) # Diffusion-weighting gradient gdiffx = make_trapezoid(channel='x', system=system, amplitude=system.max_grad * gscl[bv] * gdir[d, 0], duration=calc_duration(gdiff)) gdiffy = make_trapezoid(channel='y', system=system, amplitude=system.max_grad * gscl[bv] * gdir[d, 1], duration=calc_duration(gdiff)) gdiffz = make_trapezoid(channel='z', system=system, amplitude=system.max_grad * gscl[bv] * gdir[d, 2], duration=calc_duration(gdiff)) seq.add_block(gdiffx, gdiffy, gdiffz) # Delay for RF180 seq.add_block(make_delay(gap_te1)) # RF180 seq.add_block(gz_spoil) rf180.freq_offset = gz180.amplitude * slice_thickness * ( s - (n_slices - 1) / 2) seq.add_block(rf180, gz180) seq.add_block(gz_spoil) # Diffusion-weighting gradient seq.add_block(gdiffx, gdiffy, gdiffz) # Delay for spiral seq.add_block(make_delay(gap_te2)) # Read k-space # Imaging Gradient waveforms gx = make_arbitrary_grad(channel='x', waveform=np.squeeze( G[:, nshot].real), system=system) gy = make_arbitrary_grad(channel='y', waveform=np.squeeze( G[:, nshot].imag), system=system) seq.add_block(gx, gy, adc) # Make the spiral finish in zero - I use pre_time because I know for sure it's long enough. # Furthermore, this is after readout and TR is supposed to be long. amp_x = [G[:, nshot].real[-1], 0] amp_y = [G[:, nshot].imag[-1], 0] gx_to_zero = make_extended_trapezoid( channel='x', amplitudes=amp_x, times=[0, pre_time], system=system) gy_to_zero = make_extended_trapezoid( channel='y', amplitudes=amp_y, times=[0, pre_time], system=system) seq.add_block(gx_to_zero, gy_to_zero) seq.add_block(gx_crush, gz_crush) # Wait TR if tr_delay > 0: seq.add_block(make_delay(tr_delay)) if tPlot: seq.plot() if tReport: print(seq.test_report()) seq.check_timing() return seq, TE, TR, fatsat_str
def generate_SeqFile_EPIDiffusion(FOV, nx, ny, ns, mg, ms, reps, st, tr, fA, b_values, n_dirs, partialFourier, tPlot, tReport): #%% --- 1 - Create new Sequence Object + Parameters seq = Sequence() # ========= # Parameters # ========= i_raster_time = 100000 assert 1 / i_raster_time == seq.grad_raster_time, "Manualy inputed inverse raster time does not match the actual value." # ========= # Code parameters # ========= fatsat_enable = 0 # Fat saturation kplot = 0 # ========= # Acquisition Parameters # ========= fov = FOV Nx = nx Ny = ny n_slices = ns TR = tr # Spin-Echo parameters - TR in [s] n_TR = math.ceil( TR * i_raster_time) # Spin-Echo parameters - number of points TR bvalue = b_values # b-value [s/mm2] nbvals = np.shape(bvalue)[0] # b-value parameters ndirs = n_dirs # b-value parameters slice_thickness = st # Acquisition Parameters in [m] # ========= # Partial Fourier # ========= pF = partialFourier Nyeff = int(pF * Ny) # Number of Ny samples acquired if pF is not 1: pF_str = "_" + str(pF) + "pF" else: pF_str = "" # ========= # Gradient Scaling # ========= gscl = np.zeros(nbvals + 1) gscl[1:] = np.sqrt(bvalue / np.max(bvalue)) gdir, nb0s = difunc.get_dirs(ndirs) # ========= # Create system # ========= system = Opts(max_grad=mg, grad_unit='mT/m', max_slew=ms, slew_unit='T/m/s', rf_ringdown_time=20e-6, rf_dead_time=100e-6, adc_dead_time=10e-6) #%% --- 2 - Fat saturation if fatsat_enable: fatsat_str = "_fatsat" b0 = 1.494 sat_ppm = -3.45 sat_freq = sat_ppm * 1e-6 * b0 * system.gamma rf_fs, _, _ = make_gauss_pulse(flip_angle=110 * math.pi / 180, system=system, duration=8e-3, bandwidth=abs(sat_freq), freq_offset=sat_freq) gz_fs = make_trapezoid(channel='z', system=system, delay=calc_duration(rf_fs), area=1 / 1e-4) else: fatsat_str = "" #%% --- 3 - Slice Selection # ========= # Create 90 degree slice selection pulse and gradient # ========= flip90 = fA * pi / 180 rf, gz, _ = make_sinc_pulse(flip_angle=flip90, system=system, duration=3e-3, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4) # ========= # Refocusing pulse with spoiling gradients # ========= rf180, gz180, _ = make_sinc_pulse(flip_angle=math.pi, system=system, duration=5e-3, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4) rf180.phase_offset = math.pi / 2 gz_spoil = make_trapezoid(channel='z', system=system, area=6 / slice_thickness, duration=3e-3) #%% --- 4 - Define other gradients and ADC events delta_k = 1 / fov k_width = Nx * delta_k dwell_time = seq.grad_raster_time # Full receiver bandwith readout_time = Nx * dwell_time # T_acq (acquisition time) flat_time = math.ceil( readout_time / seq.grad_raster_time) * seq.grad_raster_time gx = make_trapezoid(channel='x', system=system, amplitude=k_width / readout_time, flat_time=flat_time) adc = make_adc(num_samples=Nx, duration=readout_time, delay=gx.rise_time + flat_time / 2 - (readout_time - dwell_time) / 2) # ========= # Pre-phasing gradients # ========= pre_time = 1e-3 gx_pre = make_trapezoid(channel='x', system=system, area=-gx.area / 2, duration=pre_time) gz_reph = make_trapezoid(channel='z', system=system, area=-gz.area / 2, duration=pre_time) gy_pre = make_trapezoid( channel='y', system=system, area=-(Ny / 2 - 0.5 - (Ny - Nyeff)) * delta_k, duration=pre_time ) # Es -0.5 y no +0.5 porque hay que pensar en areas, no en rayas! # ========= # Phase blip in shortest possible time # ========= gy = make_trapezoid(channel='y', system=system, area=delta_k) dur = math.ceil( calc_duration(gy) / seq.grad_raster_time) * seq.grad_raster_time #%% --- 5 - Obtain TE and diffusion-weighting gradient waveform # ========= # Calculate some times constant throughout the process # ========= duration_center = math.ceil( (calc_duration(gx) * (Ny / 2 + 0.5 - (Ny - Nyeff)) + calc_duration(gy) * (Ny / 2 - 0.5 - (Ny - Nyeff))) / seq.grad_raster_time) * seq.grad_raster_time rf_center_with_delay = rf.delay + calc_rf_center(rf)[0] rf180_center_with_delay = rf180.delay + calc_rf_center(rf180)[0] # ========= # Find minimum TE considering the readout times. # ========= TE = 40e-3 # [s] delay_te2 = -1 while delay_te2 <= 0: TE = TE + 0.02e-3 # [ms] delay_te2 = math.ceil((TE / 2 - calc_duration(rf180) + rf180_center_with_delay - calc_duration(gz_spoil) - \ calc_duration(gx_pre, gy_pre) - duration_center) / seq.grad_raster_time) * seq.grad_raster_time # ========= # Find minimum TE for the target b-value # ========= bvalue_tmp = 0 while bvalue_tmp < np.max(bvalue): TE = TE + 2 * seq.grad_raster_time # [ms] delay_te1 = math.ceil((TE / 2 - calc_duration(gz) + rf_center_with_delay - pre_time - calc_duration(gz_spoil) - \ rf180_center_with_delay) / seq.grad_raster_time) * seq.grad_raster_time delay_te2 = math.ceil((TE / 2 - calc_duration(rf180) + rf180_center_with_delay - calc_duration(gz_spoil) - \ calc_duration(gx_pre, gy_pre) - duration_center) / seq.grad_raster_time) * seq.grad_raster_time # Waveform Ramp time gdiff_rt = math.ceil(system.max_grad / system.max_slew / seq.grad_raster_time) * seq.grad_raster_time # Select the shortest available time gdiff_delta = min(delay_te1, delay_te2) gdiff_Delta = math.ceil( (delay_te1 + 2 * calc_duration(gz_spoil) + calc_duration(gz180)) / seq.grad_raster_time) * seq.grad_raster_time gdiff = make_trapezoid(channel='x', system=system, amplitude=system.max_grad, duration=gdiff_delta) # delta only corresponds to the rectangle. gdiff_delta = math.ceil((gdiff_delta - 2 * gdiff_rt) / seq.grad_raster_time) * seq.grad_raster_time bv = difunc.calc_bval(system.max_grad, gdiff_delta, gdiff_Delta, gdiff_rt) bvalue_tmp = bv * 1e-6 # ========= # Show final TE and b-values: # ========= print("TE:", round(TE * 1e3, 2), "ms") for bv in range(1, nbvals + 1): print( round( difunc.calc_bval(system.max_grad * gscl[bv], gdiff_delta, gdiff_Delta, gdiff_rt) * 1e-6, 2), "s/mm2") # ========= # Crusher gradients # ========= gx_crush = make_trapezoid(channel='x', area=2 * Nx * delta_k, system=system) gz_crush = make_trapezoid(channel='z', area=4 / slice_thickness, system=system) #%% --- 6 - Delays # ========= # TR delay - Takes everything into account # EPI reading time: # Distance between the center of the RF90s must be TR # ========= EPI_time = calc_duration(gx) * Nyeff + calc_duration(gy) * (Nyeff - 1) if fatsat_enable: tr_delay = math.floor( (TR - (TE - duration_center + EPI_time) - rf_center_with_delay - calc_duration(gx_crush, gz_crush) \ - calc_duration(rf_fs, gz_fs)) \ / seq.grad_raster_time) * seq.grad_raster_time else: tr_delay = math.floor( (TR - (TE - duration_center + EPI_time) - rf_center_with_delay - calc_duration(gx_crush, gz_crush)) \ / seq.grad_raster_time) * seq.grad_raster_time # ========= # Check TR delay time # ========= assert tr_delay > 0, "Such parameter configuration needs longer TR." # ========= # Delay time # ========= # ========= # Time between the gradient and the RF180. This time might be zero some times, although it is not normal. # ========= gap_te1 = math.ceil((delay_te1 - calc_duration(gdiff)) / seq.grad_raster_time) * seq.grad_raster_time # ========= # Time between the gradient and the locate k-space gradients. # ========= gap_te2 = math.ceil((delay_te2 - calc_duration(gdiff)) / seq.grad_raster_time) * seq.grad_raster_time #%% --- 9 - b-zero acquisition for d in range(nb0s): for s in range(n_slices): # Fat saturation if fatsat_enable: seq.add_block(rf_fs, gz_fs) # RF90 rf.freq_offset = gz.amplitude * slice_thickness * ( s - (n_slices - 1) / 2) seq.add_block(rf, gz) seq.add_block(gz_reph) # Delay for RF180 seq.add_block(make_delay(delay_te1)) # RF180 seq.add_block(gz_spoil) rf180.freq_offset = gz180.amplitude * slice_thickness * ( s - (n_slices - 1) / 2) seq.add_block(rf180, gz180) seq.add_block(gz_spoil) # Delay for EPI seq.add_block(make_delay(delay_te2)) # Locate k-space seq.add_block(gx_pre, gy_pre) for i in range(Nyeff): seq.add_block(gx, adc) # Read one line of k-space if i is not Nyeff - 1: seq.add_block(gy) # Phase blip gx.amplitude = -gx.amplitude # Reverse polarity of read gradient seq.add_block(gx_crush, gz_crush) # Wait TR if tr_delay > 0: seq.add_block(make_delay(tr_delay)) #%% --- 10 - DWI acquisition for bv in range(1, nbvals + 1): for d in range(ndirs): for s in range(n_slices): # Fat saturation if fatsat_enable: seq.add_block(rf_fs, gz_fs) # RF90 rf.freq_offset = gz.amplitude * slice_thickness * ( s - (n_slices - 1) / 2) seq.add_block(rf, gz) seq.add_block(gz_reph) # Diffusion-weighting gradient gdiffx = make_trapezoid(channel='x', system=system, amplitude=system.max_grad * gscl[bv] * gdir[d, 0], duration=calc_duration(gdiff)) gdiffy = make_trapezoid(channel='y', system=system, amplitude=system.max_grad * gscl[bv] * gdir[d, 1], duration=calc_duration(gdiff)) gdiffz = make_trapezoid(channel='z', system=system, amplitude=system.max_grad * gscl[bv] * gdir[d, 2], duration=calc_duration(gdiff)) seq.add_block(gdiffx, gdiffy, gdiffz) # Delay for RF180 seq.add_block(make_delay(gap_te1)) # RF180 seq.add_block(gz_spoil) rf180.freq_offset = gz180.amplitude * slice_thickness * ( s - (n_slices - 1) / 2) seq.add_block(rf180, gz180) seq.add_block(gz_spoil) # Diffusion-weighting gradient seq.add_block(gdiffx, gdiffy, gdiffz) # Delay for EPI seq.add_block(make_delay(gap_te2)) # Locate k-space seq.add_block(gx_pre, gy_pre) for i in range(Nyeff): seq.add_block(gx, adc) # Read one line of k-space if i is not Nyeff - 1: seq.add_block(gy) # Phase blip gx.amplitude = -gx.amplitude # Reverse polarity of read gradient seq.add_block(gx_crush, gz_crush) # Wait TR if tr_delay > 0: seq.add_block(make_delay(tr_delay)) if tPlot: seq.plot() if tReport: print(seq.test_report()) seq.check_timing() return seq, TE, TR, fatsat_str
def generate_GIRF_SeqFile(iT, tr, te, Npuls, mg, ms, grt, fA, n_slices, reps, sliceT, tPre, tPos, tX, tY, tPlot, tReport, rf_offset, testPRE_POST, dummy): # %% =========================================================================== # %% --- 1 - Instantiation and gradient limits --- system = Opts(max_grad=mg, grad_unit='mT/m', max_slew=ms, slew_unit='T/m/s', rf_ringdown_time=20e-6, rf_dead_time=100e-6, adc_dead_time=10e-6) seq = Sequence(system) # I need to check the manually inputed inverse raster time and the actual value are the same. i_raster_time = 100000 assert 1 / i_raster_time == seq.grad_raster_time, "Manualy inputed inverse raster time does not match the actual value." slice_thickness, slice_gap, TR, TE, rf_offset_z = sliceT, 15e-3, tr, te, 0 delta_z = n_slices * slice_thickness z = np.linspace((-delta_z / 2), (delta_z / 2), n_slices) + rf_offset_z x = np.linspace((-delta_z / 2), (delta_z / 2), n_slices) + rf_offset y = np.linspace((-delta_z / 2), (delta_z / 2), n_slices) + rf_offset # %% --- 2 - Gradients G = iT G_zero = np.zeros(len(iT[:, 0])) G_pre = np.zeros(math.floor(tPre * i_raster_time)) G_pos = np.zeros(math.floor(tPos * i_raster_time)) # %% --- 3 - Slice Selection # ========= # Create 90 degree slice selection pulse and gradient # ========= # RF90 flip90 = fA * pi / 180 rf, gz, gzr = make_sinc_pulse(flip_angle=flip90, duration=3e-3, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4, system=system) rfx, gxRF, gxr = make_sinc_pulse_channel(channel='x', flip_angle=flip90, duration=3e-3, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4, system=system) rfy, gyRF, gyr = make_sinc_pulse_channel(channel='y', flip_angle=flip90, duration=3e-3, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4, system=system) # %% --- 4 - ADCs / Readouts # timeStart = -5e-3 # timeEnd = 63e-3 # n_timeStart = math.ceil(timeStart * i_raster_time) # n_timeEnd = math.ceil(timeEnd * i_raster_time) # adc_samples = n_timeEnd - n_timeStart adc_samples = math.floor(len(G) / 4) * 4 - 1 adc_samples_pre = math.floor(len(G_pre) / 4) * 4 - 2 adc_samples_pos = math.floor(len(G_pos) / 4) * 4 - 100 adc = make_adc(num_samples=adc_samples, duration=adc_samples / i_raster_time, system=system) adc_pre = make_adc(num_samples=adc_samples_pre, duration=adc_samples_pre / i_raster_time, system=system) adc_pos = make_adc(num_samples=adc_samples_pos, duration=adc_samples_pos / i_raster_time, system=system) # %% --- 5 - Spoilers pre_time = 8e-4 n_pre_time = math.ceil(pre_time * i_raster_time) gz_rephz = make_trapezoid(channel='z', area=-gz.area / 2, duration=2e-3, system=system) gz_spoil = make_trapezoid(channel='z', area=-gz.area / 2, duration=3 * n_pre_time / i_raster_time, system=system) gx_rephz = make_trapezoid(channel='x', area=-gxRF.area / 2, duration=2e-3, system=system) gx_spoil = make_trapezoid(channel='x', area=-gxRF.area / 2, duration=3 * n_pre_time / i_raster_time, system=system) gy_rephz = make_trapezoid(channel='y', area=-gyRF.area / 2, duration=2e-3, system=system) gy_spoil = make_trapezoid(channel='y', area=-gyRF.area / 2, duration=3 * n_pre_time / i_raster_time, system=system) aux_gx = make_arbitrary_grad(channel='x', waveform=np.squeeze(G[:, 0]), system=system) aux_gy = make_arbitrary_grad(channel='y', waveform=np.squeeze(G[:, 0]), system=system) # %% --- 6 - Calculate timing/Delays # for z # delay pre ADC n_TE = math.ceil(TE * i_raster_time) n_dur_gz_rephz = math.ceil(calc_duration(gz_rephz) * i_raster_time) n_dur_rf = math.ceil(calc_duration(rf) * i_raster_time) n_del_preGRS = n_TE - (n_dur_gz_rephz + math.ceil(n_dur_rf / 2) ) # Time before input in points del_preGRS = n_del_preGRS / i_raster_time delay_preGRS = make_delay(del_preGRS) # delay pos ADC n_TR = math.ceil(TR * i_raster_time) n_dur_aux_gx = math.ceil(calc_duration(aux_gx) * i_raster_time) n_dur_adc = math.ceil(calc_duration(adc) * i_raster_time) n_dur_gz_spoil = math.ceil(calc_duration(gx_spoil) * i_raster_time) n_delTR = n_TR - (n_dur_gz_rephz + n_dur_rf + n_dur_aux_gx + n_dur_gz_spoil ) # Time after input to the system in points # n_delTR = n_TR - (n_TE + n_dur_adc + n_dur_gz_spoil) # Time after input to the system in points delTR = n_delTR / i_raster_time delayTR = make_delay(delTR) # for x # delay pre ADC n_TE = math.ceil(TE * i_raster_time) n_dur_gx_rephz = math.ceil(calc_duration(gx_rephz) * i_raster_time) n_dur_rfx = math.ceil(calc_duration(rfx) * i_raster_time) n_del_preGRS_x = n_TE - (n_dur_gx_rephz + math.ceil(n_dur_rfx / 2) ) # Time before input in points del_preGRS_x = n_del_preGRS_x / i_raster_time delay_preGRS_x = make_delay(del_preGRS_x) # delay pos ADC n_TR = math.ceil(TR * i_raster_time) n_dur_gx_spoil = math.ceil(calc_duration(gx_spoil) * i_raster_time) n_dur_adc_pre = math.ceil(calc_duration(adc_pre) * i_raster_time) n_dur_adc_pos = math.ceil(calc_duration(adc_pos) * i_raster_time) n_delTR_x = n_TR - ( n_dur_gx_rephz + math.ceil(n_dur_rfx / 2) + n_dur_adc_pre + n_dur_aux_gx + n_dur_adc_pos + n_dur_gx_spoil ) # Time after input to the system in points # n_delTR_x = n_TR - (n_TE + n_dur_adc + n_dur_gx_spoil) # Time after input to the system in points delTR_x = n_delTR_x / i_raster_time delayTR_x = make_delay(delTR_x) # for y # delay pre ADC n_TE = math.ceil(TE * i_raster_time) n_dur_gy_rephz = math.ceil(calc_duration(gy_rephz) * i_raster_time) n_dur_rfy = math.ceil(calc_duration(rfy) * i_raster_time) n_del_preGRS_y = n_TE - (n_dur_gy_rephz + math.ceil(n_dur_rfy / 2) ) # Time before input in points del_preGRS_y = n_del_preGRS_y / i_raster_time delay_preGRS_y = make_delay(del_preGRS_y) # delay pos ADC n_TR = math.ceil(TR * i_raster_time) n_dur_aux_gy = math.ceil(calc_duration(aux_gy) * i_raster_time) n_dur_gy_spoil = math.ceil(calc_duration(gy_spoil) * i_raster_time) n_delTR_y = n_TR - (n_dur_gy_rephz + math.ceil(n_dur_rfy / 2) + n_dur_adc_pre + n_dur_aux_gy + n_dur_adc_pos + n_dur_gy_spoil) # n_delTR_y = n_TR - (n_TE + n_dur_adc + n_dur_gy_spoil) # Time after input to the system in points delTR_y = n_delTR_y / i_raster_time delayTR_y = make_delay(delTR_y) # %% --- 7 - Define sequence for measuring k_trajectory - blocks/Readouts if dummy: # for x and y rf pulse freq_offset_gx = gxRF.amplitude * x[0] rfx.freq_offset = freq_offset_gx freq_offset_gy = gyRF.amplitude * y[0] rfy.freq_offset = freq_offset_gy # RF90 seq.add_block(rfx, gxRF) seq.add_block(gx_rephz) # Delay for spiral seq.add_block(delay_preGRS_x) # Read k-space - Imaging Gradient waveforms gx_zero = make_arbitrary_grad(channel='x', waveform=np.squeeze(G_zero), system=system) seq.add_block(adc, gx_zero) # Gradients Spoils seq.add_block(gx_spoil) # Delay to TR seq.add_block(delayTR_x) if tX: for ns in range(Npuls): for r in range(reps): for s in range(n_slices): # for x and y rf pulse freq_offset_gx = gxRF.amplitude * x[s] rfx.freq_offset = freq_offset_gx freq_offset_gy = gyRF.amplitude * y[s] rfy.freq_offset = freq_offset_gy # %% --- for x-axis no gradient --- %% # # RF90 seq.add_block(rfx, gxRF) seq.add_block(gx_rephz) # Delay for spiral seq.add_block(delay_preGRS_x) # Read - pre GIRF if testPRE_POST: gx_pre = make_arbitrary_grad( channel='x', waveform=np.squeeze(G_pre), system=system) seq.add_block(adc_pre, gx_pre) # Read k-space - Imaging Gradient waveforms gx_zero = make_arbitrary_grad(channel='x', waveform=np.squeeze(G_zero), system=system) seq.add_block(adc, gx_zero) # Read - pos GIRF if testPRE_POST: gx_pos = make_arbitrary_grad( channel='x', waveform=np.squeeze(G_pos), system=system) seq.add_block(adc_pos, gx_pos) # Gradients Spoils seq.add_block(gx_spoil) # Delay to TR seq.add_block(delayTR_x) # %% --- for x-axis w/ gradient --- %% # # RF90 seq.add_block(rfx, gxRF) seq.add_block(gx_rephz) # Delay for spiral seq.add_block(delay_preGRS_x) # Read - pre GIRF if testPRE_POST: gx_pre = make_arbitrary_grad( channel='x', waveform=np.squeeze(G_pre), system=system) seq.add_block(adc_pre, gx_pre) # Read k-space - Imaging Gradient waveforms gx = make_arbitrary_grad(channel='x', waveform=np.squeeze(G[:, ns]), system=system) seq.add_block(gx, adc) # Read - pos GIRF if testPRE_POST: gx_pos = make_arbitrary_grad( channel='x', waveform=np.squeeze(G_pos), system=system) seq.add_block(adc_pos, gx_pos) # Gradients Spoils seq.add_block(gx_spoil) # Delay to TR seq.add_block(delayTR_x) if tY: for ns in range(Npuls): for r in range(reps): for s in range(n_slices): # %% --- for y-axis no gradient --- %% # seq.add_block(rfy, gyRF) seq.add_block(gy_rephz) # Delay for spiral seq.add_block(delay_preGRS_y) # Read - pre GIRF if testPRE_POST: gy_pre = make_arbitrary_grad( channel='y', waveform=np.squeeze(G_pre), system=system) seq.add_block(adc_pre, gy_pre) # Read k-space - Imaging Gradient waveforms gy_zero = make_arbitrary_grad(channel='y', waveform=np.squeeze(G_zero), system=system) seq.add_block(gy_zero, adc) # Read - pos GIRF if testPRE_POST: gy_pos = make_arbitrary_grad( channel='y', waveform=np.squeeze(G_pos), system=system) seq.add_block(adc_pos, gy_pos) # Gradients Spoils seq.add_block(gy_spoil) # Delay to TR seq.add_block(delayTR_y) # %% --- for y-axis w/ gradient --- %% # # RF90 seq.add_block(rfy, gyRF) seq.add_block(gy_rephz) # Delay for spiral seq.add_block(delay_preGRS_y) # Read - pre GIRF if testPRE_POST: gy_pre = make_arbitrary_grad( channel='y', waveform=np.squeeze(G_pre), system=system) seq.add_block(adc_pre, gy_pre) # Read k-space - Imaging Gradient waveforms gy = make_arbitrary_grad(channel='y', waveform=np.squeeze(G[:, ns]), system=system) seq.add_block(gy, adc) # Read - pos GIRF if testPRE_POST: gy_pos = make_arbitrary_grad( channel='y', waveform=np.squeeze(G_pos), system=system) seq.add_block(adc_pos, gy_pos) # Gradients Spoils seq.add_block(gy_spoil) # Delay to TR seq.add_block(delayTR_y) # %% --- 8 - Plot ADCs, GX, GY, GZ, RFpulse, RFphase # # plt.figure() if tPlot: seq.plot() if tReport: print(seq.test_report()) seq.check_timing() return seq