; $Id: scanpoints__define.pro,v 1.2 2006/06/02 20:59:19 kneller Exp $
;###############################################################################
;
;
;CLASS NAME:
;    scanpoints
;
;PURPOSE:
;
;CATEGORY:
;
;
;SUPERCLASSES:
;   idl_container
;
;
;METHODS:
;    scanpoints::updateValues
;    scanpoints::qevals
;    scanpoints::createScan
;    scanpoints::calculate
;    scanPoints::cleanup
;    scanPoints::init
;    scanpoints__define
;
;
; AUTHOR:
; Larry Kneller
; NIST Center for Neutron Research
; 100 Bureau Drive, Gaithersburg, MD 20899
; United States
; kneller@nist.gov  301-975-8839
; Thu Jun 01 20:34:38 2006
;
; LICENSE:
; The software in this file is written by an employee of
; National Institute of Standards and Technology
; as part of the DAVE software project.
;
; The DAVE software package is not subject to copyright protection
; and is in the public domain. It should be considered as an
; experimental neutron scattering data reduction, visualization, and
; analysis system. As such, the authors assume no responsibility
; whatsoever for its use, and make no guarantees, expressed or
; implied, about its quality, reliability, or any other
; characteristic. The use of certain trade names or commercial
; products does not imply any endorsement of a particular product,
; nor does it imply that the named product is necessarily the best
; product for the stated purpose. We would appreciate acknowledgment
; if the DAVE software is used or if the code in this file is
; included in another product.
;
;###############################################################################

;###############################################################################
;
;NAME:
;        scanpoints::updateValues
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro scanpoints::updateValues,scanparmsobj,latparmsobj
    ;GET VALUES FROM PARMS WIDGETS
    self.latvals  = latparmsobj->get_values()
    self.scanvals = scanparmsobj->get_values()

end;updateValues

;###############################################################################
;
;NAME:
;        scanpoints::qevals
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function scanpoints::qevals
    ;CREATE 5 x npts ARRAY OF qetrans

    ;GET q

    qetrans = (self.scanvals).qetrans
    qerange = (self.scanvals).qerange
    npts    = (self.scanvals).npts

;print,'#####################'
;print,'scanpoints::qevals'
;    print,qetrans
;    print,qerange
;    print,npts
;print,'#####################'

    ;qeoffset = qerange/2.0

    hrange = qetrans[0] + (qerange[0]/npts)*findgen(npts) - qerange[0]/2.0
    krange = qetrans[1] + (qerange[1]/npts)*findgen(npts) - qerange[1]/2.0
    lrange = qetrans[2] + (qerange[2]/npts)*findgen(npts) - qerange[2]/2.0
    erange = qetrans[3] + (qerange[3]/npts)*findgen(npts) - qerange[3]/2.0
    efix   = qetrans[4]*(fltarr(npts)+1.0)
    range = [[hrange],[krange],[lrange],[erange],[efix]]

    return,range

end;qetrans

;###############################################################################
;
;NAME:
;        scanpoints::createScan
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function scanpoints::createScan,scanparmsobj,latparmsobj,showq=showq

    print,'scanPoints::createScan'
    obj = self->get(/all)
    if obj_valid(obj[0]) gt 0 then obj_destroy,obj


    self->updateValues,scanparmsobj,latparmsobj
    npts    = (self.scanvals).npts

    qevals = self->qevals()

;    help,qevals

    count = 0
    for i=0,npts-1 do begin
;        print,i,' qevals[i,*]=',transpose(qevals[i,*])
        ret = self->calculate(qevals[i,*],dat,showq=showq)
        if ret ne 0 then begin
            self->add,dat
            count = count + 1
        endif

    endfor;i

    return,count

end;createScan

;###############################################################################
;
;NAME:
;        scanpoints::calculate
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function scanpoints::calculate,qetrans,qdata,showq=showq

    ;CALCULATE PARAMETERS FOR ONE SCAN POINT.
    ;THIS WILL BE CALLED BE A METHOD THAT CREATES THE DATA OBJECTS.
    ;IF SUCCESFUL IT WILL RETURN ONE
    ;

;print,'qetrans=',transpose(qetrans)



;    ;GET VALUES FROM PARMS WIDGETS
;    lats = latparmsobj->get_values()
;    scan  = scanparmsobj->get_values()
;
;    self.latvals = latvals
;    self.scanvals = scanvals

    lats = self.latvals
    scan = self.scanvals

    ;UPDATE THE LATTICE OBJECT
    self.lattice->setproperty,$
                            la=lats.a,lb=lats.b,lc=lats.c,$
                            alpha=lats.alpha,beta=lats.beta,gamma=lats.gamma


    ;TO VECTORIZE THIS, THE qetrans KEYWORD MUST BE A VECTOR
    ;SHOULD I VECTORIZE THIS????


    ;CALCULATE THE RESOLUTION
    self.rescalculator->calculate,rm,r0,$
                                  horizontal=scan.horizontal,$
                                  collimatorh=scan.collimatorh,$
                                  collimatorv=scan.collimatorv,$
                                  mosaic=scan.mosaic,$
                                  dspacing=scan.dspacing,$
                                  instrument_orient=scan.instrument_orient,$
                                  qetrans=qetrans,$;scan.qetrans,$
                                  lattice=self.lattice,closed=closed

    if total(finite(rm,/nan)) ne 0 then return,0
    if closed eq 0 then return,0


    ;CALCULATE THE a,b,c VALUES AND THE 3x3 ROTATION MATRIX FOR THE
    ;ELLIPSOID.
       rmtransformed=self.lattice->rtransform(lats.orient1,lats.orient2,$
                                                     scan.qetrans,rm)

    ;if total(finite(rmtransformed,/nan)) gt 0 then rmtransformed = double([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]])

    eigenvalues = float(LA_EIGENPROBLEM(rmtransformed, EIGENVECTORS = eigenvectors))
    eigenvectors=float(eigenvectors)
    eiginv=invert(eigenvectors)


;#################################################
;RESET rm TO BE rmtransformed!!!!
;#################################################
    rm = rmtransformed


    ;GET a,b,c = AXES OF ELLIPSOID IN ITS NATURAL COORD SYSTEM WHERE R matrix is diagonalized
    d=sqrt(2.0*alog(2.0))

    a=d/sqrt(eigenvalues[0]);*100.0
    b=d/sqrt(eigenvalues[1]);*100.0
    c=d/sqrt(eigenvalues[2]);*10.0
    transmatrix=eigenvectors; note that this is a 4x4 matrix since it comes from the R-matrix
       ; delete the last row
    transmatrix=transmatrix[*,[0,1,2]]
       ; delete the last column
    transmatrix=transmatrix[[0,1,2],*]


;    QX = total(self.q*self.orient1)
;    self.qx = qx
;    QY = total(self.q*self.orient2)
;    self.qy = qy
;
;    E  = self.E


    ;################################################################################
    ;
    ;THESE NEXT CALCULATIONS ARE PROBABLY NOT CORRECT, BUT USE THEM FOR TESTING!!!!
    ;
    ;################################################################################
    Qx = total(qetrans[0:2]*self.latvals.orient1)
    Qy = total(qetrans[0:2]*self.latvals.orient2)
    E =  self.scanvals.qetrans[3]

;print,'#########################'
;print,'ScanPoints::calculate'
;print,'#########################'
;    print,'qx=',qx
;    print,'qy=',qy
    if n_elements(showQ) eq 0 then showQ = 1
    qdata = obj_new('spurion_scanqpoint_data',[0.],[0.],[0.],$
                                        id='SPURION_SCANQPOINT',$
                                        legend='XY',$
                                        showdata=1,$
                                        showlegend=0,$
                                        rm=rm,$
                                        r0=r0,$
                                        Qx=Qx,$            ;Qx,Qy IN THE u,v COORDINATES, i.e. IN THE SCATTERING PLANE.
                                        Qy=Qy,$
                                        kix=kix,$
                                        kiy=kiy,$
                                        kfx=kfx,$
                                        kfy=kfy,$
                                        E=E,$
                                        showellipse=1,$
                                        showQ=showQ,$
                                        showki=1,$
                                        showkf=1,$
                                        showproj=1,$
                                        showcut=1,$
                                        /xy)

    ;return,qdata
    return,1
end;calculate
;###############################################################################
;
;NAME:
;        scanPoints::cleanup
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro scanPoints::cleanup
    print,'scanPoints::cleanup'
    obj_destroy,self.lattice
    obj_destroy,self.rescalculator
    o = self->get(/all)
    if obj_valid(o[0]) gt 0 then obj_destroy,o

end;cleanup

;###############################################################################
;
;NAME:
;        scanPoints::init
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function scanPoints::init,scanparmsobj,latparmsobj,showq=showq

    scanvals = scanparmsobj->get_values()
    latvals = latparmsobj->get_values()

    self.scanvals = scanvals
    self.latvals  = latvals

    self.lattice = obj_new('lattice',latvals.a,latvals.b,latvals.c,latvals.alpha,latvals.beta,latvals.gamma)

    self.rescalculator = obj_new('Rescal2_calculator',$
                                   self.lattice,$;a, b, c, alpha, beta, gamma,$           ;LATTICE PARAMETERS
                                   scanvals.horizontal,scanvals.collimatorh,scanvals.collimatorv,$    ;RESOLUTION PARAMETERS
                                   scanvals.mosaic,scanvals.dspacing,scanvals.instrument_orient,$
                                   scanvals.qetrans)

    self.rescalculator->calculate,rm,r0, horizontal=scanvals.horizontal,$
                                    collimatorh=scanvals.collimatorh,$
                                    collimatorv=scanvals.collimatorv,$
                                    mosaic=scanvals.mosaic,$
                                    dspacing=scanvals.dspacing,$
                                    instrument_orient=scanvals.instrument_orient,$
                                    qetrans=scanvals.qetrans,$
                                    lattice=self.lattice,closed=closed




;    rmtransformed=lattice->rtransform(latvals.orient1,latvals.orient2,$
;                                                     scanvals.qetrans,rm)
;
;
;    ;SET rm TO rmtransformed FOR THE DATA OBJECTS
;    rm = rmtransformed
;
;
;    ;SET UP DUMMY DATA FOR PLOTS
;    x = [0] & y = [0] & sy = [0]
;
;    qdata = obj_new('spurion_spurion_scanqpoint_data',x,y,sy,legend='XY',$
;                                         showdata=1,$
;                                         showlegend=0,$
;                                         rm=rm,$
;                                         ro=ro,$
;                                         /xy)
;
;
;    qdata->setproperty,$
;                rm=rm,$
;                r0=r0,$
;
;                Q=scanvals.qetrans[0:2],$
;                orient1=latvals.orient1,$
;                orient2=latvals.orient2,$
;                E=scanvals.qetrans[4],$
;                astar=latvals.astar,$
;                bstar=latvals.bstar,$
;                cstar=latvals.cstar,$
;                alphastar=latvals.alphastar,$
;                betastar= latvals.betastar,$
;                gammastar=latvals.gammastar
;    qdata->calculate
;
;    self.qplotobj->add,qdata



    return,1
end;init

;###############################################################################
;
;NAME:
;        scanpoints__define
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro scanpoints__define,class

    cwo_scanparms_values_define,scanvals
    cwo_latparms_values_define,latvals

    class = {scanpoints,$
                inherits idl_container,$
                lattice:obj_new(),$
                rescalculator:obj_new(),$
                scanvals:scanvals,$
                latvals:latvals}

end;scanpoint__define


