/mc_mainloop_rev4.m

http://github.com/gallamine/Photonator · Objective C · 356 lines · 313 code · 43 blank · 0 comment · 26 complexity · f777f29354897914b69b3acf78e3ab61 MD5 · raw file

  1. % Rev 4 - switch to split mover/receiver, fix direction vector problem,
  2. % lookup table/interpolation
  3. % set up an array for the photons,
  4. % x, y, z, mu_x, mu_y, mu_z, weight, received
  5. % 0, 0, 0, 0 , 0 , 1 , 1 , 1 - initial values
  6. % 1, 2, 3, 4 , 5 , 6 , 7 , 8 - Position
  7. % photon(:,1) == X POSITION
  8. % photon(:,2) == Y POSITION
  9. % photon(:,3) == Z POSITION
  10. % photon(:,4) == ux
  11. % photon(:,5) == uy
  12. % photon(:,6) == uz
  13. % photon(:,7) == WEIGHT
  14. % photon(:,8) == RECEIVED? 1 = No, 0 = Yes
  15. % index from origin, 0 theta (angle between x and z), 0 phi (angle between x and y) along x-axis
  16. clear all
  17. clc
  18. % Program run constants
  19. num_photons = 5e5;
  20. albedo = 0.95; % Albedo of Maalox (ranges from 0.8 to 0.95)
  21. c = 2.35;
  22. receiver_z = 3.66;
  23. receiver_x = 0.20; % Y position of the receiver (in meters)
  24. receiver_y = 0; % Z position of the receiver(in meters)
  25. rec_pos = [0,0; 0,0; 0,0]; % receivers at the same position (on the x/y plane)
  26. rec_aperture = [0.0079, 0.0508, 0.0508]; % rec_aperture = ones(num_rx,1).*0.0508; % 0.0508 m = 2 inches
  27. rec_fov = [2.27, 0.0785, 0.1745]; % 0.314159 = 18 deg FOV, 2.27 = 130 deg, 0.0785 = 5 deg
  28. photon = zeros(num_photons,8);
  29. photon(:,7) = ones(num_photons,1); % set weights to one
  30. photon(:,8) = ones(num_photons,1); % set all active
  31. totaldist = zeros(num_photons,1); % record total distance traveled by each photon
  32. rec_dist = zeros(num_photons,1); % total distance photon traveld at point of reception
  33. rec_loc = zeros(num_photons,2); % location of the received photon on the z,y rec. plane
  34. total_rec_packets = 0; % Total number of packets to cross detector
  35. total_rec_power = 0; % Total power to cross detector
  36. % c = 0.5; % attenuation coefficient in m^-1
  37. % a = 0.07; % absorption coefficient in m^-1
  38. % % harbor water
  39. % c = 2.190;
  40. % a = 0.366;
  41. % [cdf_scatter,angle] = generate_scatter('calc','harbor');
  42. % % coastal water
  43. % c = 0.22 + 0.179;
  44. % a = 0.179;
  45. % [cdf_scatter,angle] = generate_scatter('calc','coastal');
  46. % Clear water
  47. % c = 0.0374 + 0.114;
  48. % a = 0.114;
  49. % [cdf_scatter,angle] = generate_scatter('calc','clear');
  50. % Calculated values
  51. b = c * albedo;
  52. a = c - b;
  53. scattering_events = ceil((c-a)*receiver_z*5) %five times the scattering attenuation length
  54. if scattering_events < 10
  55. scattering_events = 10;
  56. end
  57. num_rx = length(rec_pos);
  58. inv_c = 1/c;
  59. inv_b = 1/(c-a);
  60. % Constants and magic numbers
  61. max_uz = 0.99999;
  62. n_water = 1.33; % index of refraction of water
  63. [cdf_scatter,angle] = generate_scatter('measured','maalox_alan');
  64. i = 0;
  65. h = waitbar(0.0,'Please wait...','CreateCancelBtn','stop=true; delete(h); clear h');
  66. set(h,'Name','optional window name');
  67. scattering_length = 1;
  68. % X position of the receiver (in meters)
  69. % receiver_z = 3*inv_c; % X position of the receiver (in meters)
  70. % c = scattering_length./receiver_z;
  71. % a = c.*(1-albedo);
  72. % Photons at origin
  73. photon(:,1) = zeros(num_photons,1); % 0
  74. photon(:,2) = zeros(num_photons,1); % 0
  75. photon(:,3) = zeros(num_photons,1); % 0
  76. % point down z-axis
  77. photon(:,4) = zeros(num_photons,1); % 0
  78. photon(:,5) = zeros(num_photons,1); % 0
  79. photon(:,6) = ones(num_photons,1); % 1
  80. r_avg = 0;
  81. tic;
  82. for j = 1:scattering_events
  83. rand_array = rand(num_photons,3); % generate a matrix for each photon with rand propogation, roll, and pitch
  84. rand_array(:,3) = rand_array(:,3).*2.*pi; %% Uniformly distributed over 0 -2Pi
  85. waitbar(j/scattering_events,h,['Scattering event ' num2str(j)]);
  86. % iterate over every single photon to calculate new position and
  87. % whether it was received or not.
  88. for i = 1:num_photons
  89. % if photon hasn't been received
  90. if (photon(i,8) == 1)
  91. r = -inv_c*log(rand_array(i,1)); % randomly generate optical path length
  92. %Generate scattering angle from beam spread function
  93. minIndex = 2;
  94. maxIndex = length(cdf_scatter);
  95. midIndex = minIndex + ceil((maxIndex - minIndex)/2);
  96. while rand_array(i,2) ~= cdf_scatter(midIndex) && maxIndex > minIndex
  97. midIndex = minIndex + ceil((maxIndex - minIndex)/2);
  98. if rand_array(i,2) > cdf_scatter(midIndex)
  99. minIndex = midIndex + 1;
  100. elseif rand_array(i,2) < cdf_scatter(midIndex)
  101. maxIndex = midIndex - 1;
  102. end
  103. end
  104. midIndex = minIndex + ceil((maxIndex - minIndex)/2);
  105. k = midIndex;
  106. theta = angle(k-1) + (rand_array(i,2) - cdf_scatter(k-1))*(angle(k) - angle(k-1))/(cdf_scatter(k) - cdf_scatter(k-1)); % Linear interpolation from "angle" vector
  107. phi = rand_array(i,3); % Phi is uniformly distributed over 0-2pi
  108. % find new position increment based on PREVIOUS direction vectors (ux,uy,uz). This
  109. % takes care of the initial condition problem where photons
  110. % were scattered immediately on the first iteration.
  111. x_step = r*photon(i,4); % x step size
  112. y_step = r*photon(i,5); % y step size
  113. z_step = r*photon(i,6); % z step size
  114. % if the photon moves past the receiver plane
  115. if ((photon(i,3) + z_step) >= receiver_z)
  116. % current_theta = acos(photon(i,6)); % cos^-1(uz)
  117. % if photon(i,6) ~= 1
  118. % if photon(i,5) >= 0
  119. % current_phi = acos(photon(i,4)/sqrt(1-photon(i,6)^2)); % cos^-1(ux/sqrt(1-uz^2))
  120. % else
  121. % current_phi = 2*pi - acos(photon(i,4)/sqrt(1-photon(i,6)^2)); % cos^-1(ux/sqrt(1-uz^2))
  122. % end
  123. % else
  124. % current_phi = rand()*2.*pi;
  125. % end
  126. % if ~isreal(current_phi)
  127. % format long
  128. % current_phi
  129. % photon(i,:)
  130. % disp('Invalid phi');
  131. % current_phi = real(current_phi);
  132. % end
  133. % FIX THESE EQUATIONS!!
  134. % z distance to receiver plane
  135. z_dist_rec_intersection = receiver_z - photon(i,3);
  136. if photon(i,6) ~= 0
  137. % y distance to receiver plane
  138. y_dist_rec_intersection = z_dist_rec_intersection*photon(i,5)/photon(i,6); % z * uy/uz = z*tan(theta)*sin(phi)
  139. % x distance to receiver plane
  140. x_dist_rec_intersection = z_dist_rec_intersection*photon(i,4)/photon(i,6); % z*ux/uz = z*tan(theta)*cos(phi)
  141. else
  142. disp('how can the photon cross the receiver plane when it"s pointing straight up???');
  143. end
  144. % euclidian distance to the reciever plane
  145. %dist_to_rec = sqrt((x_dist_rec_intersection)^2 + (y_dist_rec_intersection)^2 + (z_dist_rec_intersection)^2);
  146. dist_to_rec = z_dist_rec_intersection / photon(i,6); % z / mu_z
  147. rec_loc(i,1) = photon(i,1) + x_dist_rec_intersection; % x-axis location of reception
  148. rec_loc(i,2) = photon(i,2) + y_dist_rec_intersection; % y-axis location of reception
  149. rec_loc(i,3) = acos(photon(i,6)); % incident angle
  150. rec_loc(i,4) = photon(i,4); % for statistics, should be uniform
  151. total_rec_packets = total_rec_packets + 1;
  152. % total_rec_power = total_rec_power + photon(i,7)*exp(-dist_to_rec*a);
  153. total_rec_power = total_rec_power + photon(i,7);
  154. rec_dist(i) = totaldist(i)+ dist_to_rec;
  155. photon(i,8) = 0;
  156. totaldist(i) = totaldist(i) + dist_to_rec;
  157. else % if the photon didn't move into the detector, reduce its power & move it
  158. % move to new x position
  159. photon(i,1) = photon(i,1) + x_step;
  160. % move to new y position
  161. photon(i,2) = photon(i,2) + y_step;
  162. % move to new z position
  163. photon(i,3) = photon(i,3) + z_step;
  164. if abs(photon(i,6)) > max_uz % if uz ~ 1
  165. %photon(i,:)
  166. photon(i,4) = sin(theta)*cos(phi);
  167. photon(i,5) = sin(theta)*sin(phi);
  168. photon(i,6) = sign(photon(i,6))*cos(theta);
  169. %disp('mu_z near 1')
  170. else
  171. sqrt_uz = sqrt(1 - photon(i,6)^2);
  172. old_ux = photon(i,4);
  173. old_uy = photon(i,5);
  174. old_uz = photon(i,6);
  175. photon(i,4) = (sin(theta)/sqrt_uz)*(old_ux*old_uz*cos(phi) - old_uy*sin(phi)) + old_ux*cos(theta); % ux
  176. photon(i,5) = (sin(theta)/sqrt_uz)*(old_uy*old_uz*cos(phi) + old_ux*sin(phi)) + old_uy*cos(theta); % uy
  177. photon(i,6) = (-sin(theta)*cos(phi))*sqrt_uz + old_uz*cos(theta); % uz
  178. %disp('mu_z less than 1')
  179. end
  180. % update the total distance the photon has traveled
  181. totaldist(i) = totaldist(i) + r;
  182. end
  183. end
  184. end
  185. %r_avg = r_avg/num_photons;
  186. % figure(1)
  187. % subplot(3,3,j)
  188. % scatter(photon(:,1),photon(:,2),50,log10(photon(:,7)),'.')
  189. % xlim([-15 50]);
  190. % ylim([-25 25]);
  191. % % xlabel('x-axis (m)')
  192. % % xlabel('y-axis (m)')
  193. end
  194. rec_loc_final = ones(total_rec_packets,4);
  195. j = 1;
  196. for i = 1:num_photons
  197. if (photon(i,8) == 0)
  198. rec_loc_final(j,:) = rec_loc(i,:);
  199. j = j +1;
  200. end
  201. end
  202. j = 1;
  203. total_rec_dist = zeros(total_rec_packets,1);
  204. total_rec_power = 0;
  205. for i = 1:num_photons
  206. if (photon(i,8) == 0)
  207. total_rec_dist(j) = rec_dist(i);
  208. total_rec_power = total_rec_power + exp(-a*rec_dist(i));
  209. j = j + 1;
  210. end
  211. end
  212. [power,ph_cnt,angle_mean,angle_var,power_mean,power_var] = mc_rec_r3(a,rec_loc_final,total_rec_dist,rec_pos,rec_aperture,rec_fov);
  213. power/num_photons % Total received power / total transmitted photon packets
  214. sd_power = sqrt(power_var).*ph_cnt/num_photons; % sd_power = sd_photon*rx_photons/total_photons.
  215. total_time = toc;
  216. minutes_to_run = total_time/60
  217. % figure(8) % plot 3D histogram of photons on RX plane
  218. % hist3([rec_loc_final(:,1),rec_loc_final(:,2)],[100 100])
  219. % set(gcf,'renderer','opengl');
  220. % set(get(gca,'child'),'FaceColor','interp','CDataMode','auto');
  221. % j = 1;
  222. % scattered_times = zeros(total_rec_packets,1);
  223. % for i = 1:num_photons
  224. %
  225. % if (photon(i,7) == 0)
  226. % scattered_times(j) = photon(i,8);
  227. % j = j + 1;
  228. % end
  229. % end
  230. total_rec_power
  231. total_rec_packets
  232. % hist(scattered_times,[0:10]);
  233. close(h)
  234. % figure(10) % Plot histogram of time-of-arrival vs. power
  235. % [N,X] = hist(total_rec_dist,100);
  236. % pwr_rx_hist = N.*exp(-a.*X);
  237. % stem(X/(3e8/n_water),pwr_rx_hist/total_rec_power)
  238. % xlabel('Time of arrival (sec)')
  239. % ylabel('Percentage of power')
  240. % distance_delta = max(X) - min(X);
  241. % time_delta = distance_delta/(3e8/n_water);
  242. % T = mean(X(2:end) - X(1:end-1))/(3e8/n_water); % Effective "sampling rate" of the histogram
  243. % bandwidth = 1/T; % Normalized frequency in Hz
  244. % figure(7)
  245. % freqz(N/total_rec_packets,[1],512,bandwidth) %% plot a frequency response from the histogram data
  246. % figure(9) %% Scatter plot of photons on RX plane
  247. % scatter(rec_loc(:,1),rec_loc(:,2))
  248. % figure(1)
  249. % scatter(photon(:,1),photon(:,2),50,log10(photon(:,7)),'.')
  250. % xlim([-20 150]);
  251. % ylim([-120 120]);
  252. % xlabel('x-axis (m)')
  253. % xlabel('y-axis (m)')
  254. %
  255. % figure(4)
  256. % scatter3(photon(:,1),photon(:,2),photon(:,3),50,log10(photon(:,7)),'.')
  257. % % Draw the box representing the receiver
  258. % line([receiver_z receiver_z],[receiver_y_min receiver_y_min],[receiver_z_max receiver_z_min],'LineWidth',4) % |
  259. % line([receiver_z receiver_z],[receiver_y_min receiver_y_max],[receiver_z_max receiver_z_max],'LineWidth',4) % -
  260. % line([receiver_z receiver_z],[receiver_y_max receiver_y_max],[receiver_z_max receiver_z_min],'LineWidth',4) % |
  261. % line([receiver_z receiver_z],[receiver_y_min receiver_y_max],[receiver_z_min receiver_z_min],'LineWidth',4) % _
  262. % xlabel('x-axis (m)')
  263. % ylabel('y-axis (m)')
  264. % zlabel('z-axis (m)')
  265. % figure(3);
  266. % hist(photon(:,1),max(photon(:,1)));
  267. % figure(2)
  268. % hist(totaldist,20);
  269. % figure(3)
  270. % hist(photon(:,4),20)
  271. findfigs
  272. sprintf('Simulation on DATE with %d photons, %d scattering events.', num_photons, scattering_events)
  273. sprintf('C = %d (1/m), A = %d (1/m).',c,a)
  274. sprintf('Receiver at %d, %d, %d (meters)',receiver_x, receiver_y, receiver_z)
  275. % sprintf('Travel distance delta %d (m). Time of arrival delta %d (sec)', distance_delta, time_delta)
  276. % sprintf('Time delta between histogram bins: %d (sec), %d (Hz)',T,bandwidth)