;+
;
; Project   : s3drs reconstruction software
;                   
; Name      : p_generate_pixon
;               
; Purpose   : part of Pixon, part of the s3drs GUI
;               
; Explanation: part of the Pixon wrappers used to access and
; manipulate the various arcane Pixon structures and objects.
;
; Originally very complex, now it basically just is a wrapper that
; checks a few things then calls 'p_osetup,pxwrapper,timage,oPixon'
;               
; Use       : typically called from 's3drs.pro' 
;    
; Inputs    : (various)
;               
; Outputs   : (various)
;
; Keywords  : (various)
;               
; Common    : none
;               
; Restrictions: none
;               
; Side effects: none
;               
; Category    : reconstruction, pixon
;               
; Prev. Hist. : None.
;
; Written     : Sandy Antunes, NRC, March-April 2005-2009
;               
;-            
pro p_generate_pixon,pixontype,pxwrapper,oPixon,image=image,N=N,raw=raw,$
                     local=local
;+
; $Id: p_generate_pixon.pro,v 1.1 2009/04/22 19:22:22 antunes Exp $
;
; Project   : developer area for STEREO SECCHI
;                   
; Name      : p_generate_pixon.pro
;               
; Purpose   : Makes the pixon object.
;               
; Explanation: Given Pixon structures and a timage cube, sets up the
;              Pixon object.
;               
; Use       : IDL> p_generate_pixon,pxwrapper,oPixon 
;    
; Inputs    :
;            sr : Pixon structure
;            sp : Pixon structure
;            sc : Pixon structure
;            sf : tPixon bookkeeping structure
;            userstruct : oPixon structure
;            image: N^3 n_e cube array
;               
; Outputs   :
;            oPixon: classic Pixon object
;            image: N^3 n_e cube array
;
; Keywords  : none
;               
; Calls from LASCO : none 
;
; Common    : none 
;               
; Restrictions: none
;               
; Side effects: none
;               
; Category    : Simulation
;               
; Prev. Hist. : See Paul Reiser's code and notes.
;
; Written     : Sandy Antunes, NRL, Nov-Dec 2005
;               
; $Log: p_generate_pixon.pro,v $
; Revision 1.1  2009/04/22 19:22:22  antunes
; code relocation part 2 of 3.
;
; Revision 1.24  2009/03/31 14:57:30  antunes
; Re-org prepatory to checking into SSW.
;
; Revision 1.23  2008/01/04 20:16:49  antunes
; Final units (hopefully), also more tests and tools.
;
; Revision 1.22  2007/10/03 18:44:20  antunes
; Implemented spherical coordinates in cpixon, major update!
;
; Revision 1.21  2007/09/14 13:40:05  antunes
; Improved scaling.
;
; Revision 1.20  2007/08/28 15:35:05  antunes
; Better automated running on real data.
;
; Revision 1.19  2007/06/29 18:12:49  antunes
; more docs
;
; Revision 1.18  2007/06/21 18:29:35  antunes
; Finished test cases and got issues reconciled.
;
; Revision 1.17  2007/05/21 18:49:15  antunes
; Added better handling of SIM data.
;
; Revision 1.16  2007/04/19 18:53:28  antunes
; Removed center_pixon for real data, added documentation.
;
; Revision 1.15  2007/03/26 17:44:23  antunes
; Fixed Pixon normalization woes, added documentation of entire Pixon flow.
;
; Revision 1.14  2007/02/21 16:43:19  antunes
; Memory mods to allow for higher N (N=256 now works!)
;
; Revision 1.13  2007/02/12 18:05:18  antunes
; Modified for better handling of optical and sun center.
; Also generalized some earlier pixon legacy code.
;
; Revision 1.12  2007/01/11 21:09:49  antunes
; Updated the plotting.
;
; Revision 1.11  2006/12/08 18:12:30  antunes
; Better plotting, time handling, etc.
;
; Revision 1.10  2006/11/30 20:03:57  antunes
; Updated pixon and other printing and output routines.
;
; Revision 1.9  2006/11/16 19:33:06  antunes
; Successfully replaced k0 with p_getk0 to allow for pointers
; and thus dynamic image loading.
;
; Revision 1.8  2006/11/16 18:27:33  antunes
; Did a rollback then an update to allow pixon wrapper to handle
; heterogeneous images.
;
; Revision 1.6  2006/05/25 18:18:30  antunes
; Better handling.
;
; Revision 1.5  2006/05/11 13:52:06  antunes
; Better handling of args, memory.
;
; Revision 1.4  2006/05/02 18:47:58  antunes
; Added test wrappers for Pixon tests.
;
; Revision 1.3  2006/04/24 19:04:01  antunes
; Fixed shared c/t pixon path environment problem.  Redid GUI to
; use widget struct rather than common so it's reentrant.  Also
; added in better comments, user input.  Now GUI is ready for
; prime time for render testing.
;
; Revision 1.2  2006/04/14 18:44:42  antunes
; Streamlined pixon, plus bugfixes.
;
; Revision 1.1  2006/04/11 15:55:05  antunes
; Massive re-org of cvs 'dev' preparatory to moving into solarsoft.
;
; Revision 1.19  2006/03/24 17:53:20  antunes
; Reconciled c and t environments, created test cases and profiling
; checks, working towards generalized tetra object.
;
; Revision 1.18  2006/03/20 19:52:07  antunes
; Code cleanup.
;
; Revision 1.17  2006/03/16 14:44:13  antunes
; Axes improvements and better handling of model params.
;
; Revision 1.16  2006/03/09 20:10:40  antunes
; Better graphic handling.
;
; Revision 1.15  2006/03/08 19:33:11  antunes
; Yet another refactoring.
;
; Revision 1.14  2006/03/08 17:52:23  antunes
; Abstracted pixon structures into an aggregate structure in order
; to be encapsulate Pixonisms from general rendering and reconstruction
; routines.
;
; Revision 1.13  2006/02/28 19:48:16  antunes
; Lots of code, some buggy-- interim checkin.
;
; Revision 1.12  2006/02/21 19:36:03  antunes
; Bug fixes and streamlining.
;
; Revision 1.11  2006/02/21 18:10:18  antunes
; Improved shared code for C and T pixon.
;
; Revision 1.10  2006/02/17 19:48:16  antunes
; Incorporated refactored TPixon code into generalized schema,
; also now they can share an environment.  They now fork in
; the 'p_generate_pixon' call.
;
; Revision 1.9  2005/12/27 17:48:24  antunes
; Commented half of the routines using SSW style.  Also added a new
; axes test case 'arrowcube'.
; Checked in the Tomography/old/mikic_img.pro routine here because it
; is a dependency for the general image-prep routine 'get_timage.pro'
;
;-            
; makes the pixon object

  raw=KEYWORD_SET(raw); whether to normalize image to n0 or not, default=normalize
  local=KEYWORD_SET(local); a path choice flag for testing

; set N based on data

if (n_elements(image) ne 0) then begin
    ; if given an image, us that image's N
    Ncube=(size(image))[1]
end else begin
    if (n_elements(N) eq 0) then Ncube=pxwrapper.sr.Ncube else Ncube=N
end

; we temporary make a shmmapped value here to manipulate, so
; that we avoid altering the original 'image' data item.
; we then shmunmap/free this temporary 'timage' after the
; Pixon object is created.  Believed handy for large N runs to
; avoid memory thrashing.

  if (pxwrapper.sc.doubleprec) then begin
      shmmap,/DOUBLE,DIMENSION=[Ncube,Ncube,Ncube],GET_NAME=segname;largearray
      timage=ptr_new(shmvar(segname),/NO_COPY)
      if (raw) then *timage=*timage*0.0+1/double(Ncube) else *timage=*timage*0.0+1/(pxwrapper.sr.n0*Ncube)
  end else begin
      shmmap,/FLOAT,DIMENSION=[Ncube,Ncube,Ncube],GET_NAME=segname ; TEST FLOAT
      timage=ptr_new(shmvar(segname),/NO_COPY)
      if (raw) then *timage=*timage*0.0+1/float(Ncube) else *timage=*timage*0.0+1/(pxwrapper.sr.n0*Ncube) ; TEST FLOAT
  end

  if (n_elements(image) ne 0) then *timage=*timage*image
;help,timage
;help,*timage

;;;;if (n_elements(image) ne 0) then begin
;;;;  if (raw) then *timage=image else *timage=image/pxwrapper.sr.n0
;;;;end else begin
    ; if not forced in invocation, use pre-stored structure's N

;;;;    newimage=shmvar(segname); largearray

;    openw, uimage, 'temp_image',/delete,/get_lun
;    temp=fake_ne_cube(Ncube)
;    image = ptr_new(ASSOC(uimage,temp))
;    ASSIGN,*image, temp, 0,/TEMP
;    image=fake_ne_cube(Ncube); make a default dull timage as placeholder
;;;;     image=dblarr(Ncube,Ncube,Ncube)+1/double(Ncube)

;;;;end

if (Ncube ne pxwrapper.sr.Ncube) then begin
  print,'Warning, Ncube in wrapper not the same as the image'
  print,'  you have passed.  Problems in geometry will result.'
  print,'  Please redo with an appropriate Ncube image size.'
end

;print,"Ncube is ",Ncube
; redo N-based structure elements
;pxwrapper.sr.Ncube=Ncube
;pxwrapper.sr.k0=0.5*(Ncube-1)
;pxwrapper.sr.lla0 = [1,1,1]*0.5*(Ncube-1)
;pxwrapper.sr.L0tau=60./double(Ncube)

;print,'invoking everything in pro_cfluxrope'

; first check if environment is set yet
  if (pixontype eq 'old') then pixontype='classic'; alias
  if (pixontype eq 'new') then pixontype='tetra'; alias

  spherical=0; no change as of yet
  if (pixontype eq 'classic' or pixontype eq 'planar') then begin
;      print,'loading classic environment'
      ; 'planar' indicates earlier Paul legacy code
      if (pixontype ne 'planar') then spherical=1
      pixontype='c'
      pixon_env,pixontype,local=local
  end else if (pixontype eq 'tetra') then begin
;      print,'loading tetrahedral environment'
      pixontype='t'
      pixon_env,pixontype,local=local
  end else begin
      print,'cannot figure out Pixon type:',pixontype,', exiting.'
      stop
  end

; Note we have two possible methods for rendering-- the original
; Paul co-planar one (rotmethod=0) or the new Sandy spherical
; geometry via rotation one (rotmethod=-1).  We use a global
; toggle here to set these.
; These values get stored into 'roco' as 0 (no z-axis rotation and no
; gamma/theta shift, so only in-plane images allowed), or
; -1 (use full spherical geometry at some performance cost, allows
; theta not in plane.)
;
; values for roco are 0 (no z-axis rotation and no gamma/theta shift,
; so only in-plane images allowed), 1 (direct z-axis view, a Paul hack),
; or -1 (use full spherical geometry at some performance cost, allows
; theta not in plane.)
;
; note use of roco to decide whether to use the full spherical
; model (roco=-1) or Paul's original co-planer system (roco=0)
; Gamma is used to set up the orientation matrices, while the
; rho is the value of gamma stored in the user struct for the
; dsf/dsft renderers.  Paul's co-planar requires gamma=rho to
; set the orientation matrices but does not allow for rotations
; above the plane.  Sandy's spherical code requires rho=gamma so
; that the rotational angle is stored in the userstruct but then
; sets the gamma stored as 0, so that the orientation matrices
; are always face-on.
  if (spherical) then begin
      pxwrapper.sr.roco=(pxwrapper.sr.roco*0) - 1
;      pxwrapper.sr.gamma=pxwrapper.sr.gamma*0.0; set to 0 to allow rotation
  end

;  print,'Invoking center_data'
;  p_center_data,pxwrapper.sr
;  pxwrapper.sr.k0=pxwrapper.sr.k0+[1,1]*.0001

  ; delete existing object, if any
  if (n_elements(oPixon) ne 0) then begin
      if (datatype(oPixon) eq 'OBJ') then Obj_Destroy, oPixon
  end

  ; now actually do useful pixon setups
  if (pixontype eq 'c') then begin
      p_osetup,pxwrapper,timage,oPixon
  end else if (pixontype eq 't') then begin
      p_tsetup,pxwrapper,image,oPixon
  end

;;;  shmunmap,segname
;;;  ptr_free,timage

  pxwrapper.object = pixontype; inform that object now exists

; DONE!
; ALL the stuff below is earlier versions of the above, commented out


;  if (pixontype eq 'c') then begin
;
      ; shift by 1 pixel?
;      pxwrapper.sr.k0=pxwrapper.sr.k0 - 0.25
;;      for m=0,n_elements(pxwrapper.sr.k0)-1 do begin
;;          pxwrapper.sr.k0[m] = ptr_new( p_getk0(pxwrapper.sr,m,shift=-0.25) )
;;          pxwrapper.sr.sunk0[m] = ptr_new( p_getk0(pxwrapper.sr,m,shift=-0.25,/sun) )
;;      end

;;;      timage=image/1.0e6/0.2   ; norm to datamax ~ 1
;      if (raw) then timage=image else timage=image/pxwrapper.sr.n0
;      timage=*image/1.0e6/0.2   ; largearray
;
      ; p_osetup is a refactor of stereo_osetup, which also
      ; changes the oPixon.user structure to allow for heterogenous N
;      p_osetup,pxwrapper,timage,oPixon
;      stereo_osetup,pxwrapper,timage,oPixon
;  end else if (pixontype eq 't') then begin
;      stereo_tsetup,pxwrapper
;      tpxn_make,pxwrapper,image,oPixon
;      p_tsetup,pxwrapper,image,oPixon
;  end
;;

;  pxwrapper.object = pixontype; inform that object now exists

;  if (pixontype eq 'c') then begin
;
;      print,'1) Now either bring in data as datum=dblarr(N,N,Nd), or run:'
;      print,"     datum=stereo_project('c',pxwrapper,oPixon)"
;      print,'     to create the first set of data projections.'
;      print,' '
;      print,'   You can view initial datum with:'
;      print,"     tv_multi,datum[,rescale=N,title='X',grid='yes',ps='no']"
;      print,' '
;      print,'2) To reconstruct type:'
;      print,"   run_pixon,pxwrapper,datum,timage,oPixon"
;
;  end else if (pixontype eq 't') then begin
;
;      print,'1) Now either bring in data as datum=dblarr(N,N,Nd), or run:'
;      print,"    datum=stereo_project('t',pxwrapper,oPixon)"
;      print,'     to create the first set of data projections.'
;      print,' '
;      print,'   You can view initial datum with:'
;      print,"     tv_multi,datum[,rescale=N,title='X',grid='yes',ps='no']"
;      print,' '
;      print,'2) To reconstruct type:'
;      print,"   run_pixon,pxwrapper,datum,timage,oPixon"
;
;  end

end
