1function [adcSegments,adcSamplesPerSegment] = calcAdcSeg(numSamples,dwell,system,mode)
2%mr.calcAdcSeg : Calculate splitting of the ADC in segments
3% On some scanners, notably Siemens, ADC objects that exceed a certain
4% sample length (8192 samples on Siemens) should be splittable to N
5% equal parts, each of which aligned to the gradient raster. Each
6% segment, however, needs to have the number of samples smaller than
7% system.adcSamplesLimit and divisible by system.adcSamplesDivisor to be
8% executable on the scanner. The optional parameter mode can be either
9% 'shorten' or 'lengthen'.
11if system.adcSamplesLimit<=0
12 adcSamplesPerSegment=numSamples;
13 adcSegments=1;
14 return;
15end
17if ~exist('mode', 'var')
18 mode='shorten';
19end
21if ~strcmp(mode,'shorten') && ~strcmp(mode,'lengthen')
22 error('In mr.calcAdcSeg(...,mode) mode should be either ''shorten'' or ''lengthen''');
23end
25t_eps=1e-9; % TODO: shift it to the system parameters???
27iGR=round(system.gradRasterTime/system.adcRasterTime);
28assert(abs(system.gradRasterTime/system.adcRasterTime-iGR)<t_eps);
30iDwell=round(dwell/system.adcRasterTime);
31assert(abs(dwell/system.adcRasterTime-iDwell)<t_eps);
33iCommon=lcm(iGR,iDwell); % least common multiplier
34samplesStep=iCommon/iDwell;
36% Siemens-specific: number of samples should be divisible by system.adcSamplesDivisor
37gcd_adcDiv=gcd(samplesStep,system.adcSamplesDivisor);
38if gcd_adcDiv~=system.adcSamplesDivisor
39 samplesStep=samplesStep*system.adcSamplesDivisor/gcd_adcDiv;
40end
42if strcmp(mode,'shorten')
43 numSamplesStepped=floor(numSamples/samplesStep);
44else
45 numSamplesStepped=ceil(numSamples/samplesStep);
46end
48while numSamplesStepped>0 && numSamplesStepped<2*numSamples/samplesStep
49 adcSegmentFactors=factor(numSamplesStepped);
50 adcSegments=1;
51 if(length(adcSegmentFactors)>1)
52 % we try all permutations and pick the smallest number of segments
53 adcSegmentFactorsPerm=perms(adcSegmentFactors);
54 adcSegmentFactorsPermProd=cumprod(adcSegmentFactorsPerm');
55 adcSegmentCandidates=unique(adcSegmentFactorsPermProd(:)); % this sorts the sequence
56 for i=1:(length(adcSegmentCandidates)-1)
57 adcSegments=adcSegmentCandidates(i);
58 adcSamplesPerSegment=numSamplesStepped*samplesStep/adcSegments;
59 if (adcSamplesPerSegment<=system.adcSamplesLimit && adcSegments<=128)
60 break
61 end
62 end
63 else
64 adcSamplesPerSegment=numSamplesStepped*samplesStep;
65 end
66 if (adcSamplesPerSegment<=system.adcSamplesLimit && adcSegments<=128)
67 break
68 end
69 if strcmp(mode,'shorten')
70 numSamplesStepped=numSamplesStepped-1; % try again with a smaller number of samples
71 else
72 numSamplesStepped=numSamplesStepped+1; % try again with a greater number of samples
73 end
75end
76assert(numSamplesStepped>0); % we could not find a suitable segmentation...
77assert(adcSamplesPerSegment>0);
78assert(adcSegments<=128);
79end