!
!----------------------------------------------------------------------
!
! <DOCUMENTATION name="modulePakoCalibrate">
!   <VERSION>
!                Id: modulePakoCalibrate.f90,v 1.2.3 2014-10-24 Hans Ungerechts
!                Id: modulePakoCalibrate.f90,v 1.2.3 2014-02-03 Hans Ungerechts
!                                              1.2.2 2013-01-17 Hans Ungerechts
!                                              1.2.1 2012-08-16 Hans Ungerechts
!                based on
!                Id: modulePakoCalibrate.f90,v 1.1.0 2009-03-31 Hans Ungerechts
!   </VERSION>
!   <PROGRAM>
!                Pako
!   </PROGRAM>
!   <FAMILY>
!                Observing Modes
!   </FAMILY>
!   <SIBLINGS>
!                Calibrate
!                Focus
!                OnOff
!                OtfMap
!                Pointing
!                Tip
!                Track
!                VLBI
!   </SIBLINGS>        
!
!   Pako module for command: CALIBRATE
!
! </DOCUMENTATION> <!-- name="modulePakoCalibrate" -->
!
!----------------------------------------------------------------------
!
Module modulePakoCalibrate
  !
  Use modulePakoMessages
  Use modulePakoTypes
  Use modulePakoGlobalParameters
  Use modulePakoLimits
  Use modulePakoXML
  Use modulePakoUtilities
  Use modulePakoPlots
  Use modulePakoDisplayText
  Use modulePakoGlobalVariables
  Use modulePakoSubscanList
  Use modulePakoReceiver
  Use modulePakoBackend
  Use modulePakoSource
  !!? TBD 2.0:   Use modulePakoSwBeam
  !!? TBD 2.0:   Use modulePakoSwFrequency
  !!? TBD 2.0:   Use modulePakoSwWobbler
  Use modulePakoSwTotalPower
  !
  Use gbl_message
  !
  Implicit None
  Save
  Private
  Public :: calibrate, displayCalibrate, saveCalibrate, startCalibrate
  !     
  ! *** Variables for Calibrate ***
  Include 'inc/variables/variablesCalibrate.inc'
!!!   
!!!   
Contains
!!!
!!!
  Subroutine CALIBRATE(programName,line,command,error)
    !
    ! *** Arguments ***
    Include 'inc/variables/headerForCommandHandler.inc'
    !
    ! *** standard working variables ***
    Include 'inc/variables/standardWorkingVariables.inc'
    !
    ! *** special working variables:   ***
    Integer    ::   nSubscans
    Logical    ::   isConnected
    !
    Character (len=lenCh) :: bolometerName
    !
    Include 'inc/ranges/rangesCalibrate.inc'
    !
    ERROR = .False.
    !
    Call pako_message(seve%t,programName,                                        &
         &  " module Calibrate, v 1.2.3 2014-02-03 ---> SR: Calibrate ")         ! trace execution
    Call pako_message(seve%t,programName,                                        &
         &  " module Calibrate, v 1.2.3 test in GILDAS feb17 ")                  ! trace execution
    !
    ! *** initialize:   ***
    If (.Not.isInitialized) Then
       Include 'inc/variables/setDefaults.inc'
       isInitialized = .True.
    Endif
    !
    ! *** set In-values = previous Values ***
    If (.Not.ERROR) Then
       vars   (iIn) = vars   (iValue)
    End If
    !
    ! *** check N of Parameters: 0, n --> at  most n allowed  ***
    Call checkNofParameters(command,                                             &
         &     0, 0,                                                             &
         &     nArguments,                                                       &
         &     errorNumber)                                                      !
    ERROR = ERROR .Or. errorNumber
    !
    ! *** check for alternative Options   ***
!!OLD      If (.Not. ERROR) Then
!!OLD         Include 'inc/options/alternative.inc'
!!OLD      End If
    !
    ! *** read Parameters, Options (to detect errors)            
    !     and check for validity and ranges                      
    If (.Not. ERROR) Then
       Call pakoMessageSwitch (setOn = .True.)
       Include 'inc/options/readOptionsCalibrate.inc'
    End If
    !
    ! *** set defaults   ***
    If (.Not. ERROR) Then
       option = 'DEFAULTS'
       Call indexCommmandOption                                                  &
            &        (command,option,commandFull,optionFull,                     &
            &        commandIndex,optionIndex,iCommand,iOption,                  &
            &        errorNotFound,errorNotUnique)                               !
       setDefaults = SIC_PRESENT(iOption,0)                
       If (setDefaults) Then
          Include 'inc/variables/setDefaults.inc'
       Endif
    Endif
    !
    ! *** Read Parameters, Options (again, after defaults!)   ***
    ! *** and check for validity and ranges                   ***
    If (.Not. ERROR) Then
       Call pakoMessageSwitch (setOff = .True.)
       Include 'inc/options/readOptionsCalibrate.inc'
    End If
    Call pakoMessageSwitch (setOn = .True.)
    !
    ! *** check consistency and                           ***
    ! *** store into temporary (intermediate) variables   ***
    If (.Not.ERROR) Then
       !
       errorInconsistent = .False.
       !
       Include 'inc/options/checkConsistentCalibrate.inc'
       !
       If (.Not. errorInconsistent) Then
          vars   (iTemp) = vars   (iIn)
       End If
       !
    End If
    !
    ERROR = ERROR .Or. errorInconsistent
    !
    ! *** evaluate consequences  / rules
    !
    If (.Not. ERROR) Then
       !
       If (vars(iTemp)%doGainImage) Then
          vars(iTemp)%doAmbient    = .True.
          vars(iTemp)%doCold       = .True.
          vars(iTemp)%doSky        = .False.
          vars(iTemp)%doGrid       = .False.
          messageText = "implies specific subscans!"
          Call PakoMessage(priorityI,severityI,                                  &
               &           "calibrate"//" /gainImage ",messageText)              !
       End If
       !
       If (vars(iTemp)%doGrid) Then
          vars(iTemp)%doAmbient    = .True.
          vars(iTemp)%doCold       = .True.
          !
          OPTION = 'SKY'
          Call indexCommmandOption                                               &
               &     (command,option,commandFull,optionFull,                     &
               &      commandIndex,optionIndex,iCommand,iOption,                 &
               &      errorNotFound,errorNotUnique)                              !
          If (.Not.SIC_PRESENT(iOption,0)) Then
             vars(iTemp)%doSky        = .True.
          End If
          vars(iTemp)%doGainImage  = .False.
          messageText = "implies specific subscans!"
          Call PakoMessage(priorityI,severityI,                                  &
               &           "calibrate"//" /grid ",messageText)                   !
          If (.Not.vars(iTemp)%doSky) Then
             messageText = "should normally be done with /SKY!"
             Call PakoMessage(priorityW,severityW,                               &
                  &           "calibrate"//" /grid ",messageText)                !
          End If
       End If
       !
    End If
    !
    ! *** conclude alternative options   ***
!!OLD      If (.Not.error) Then
!!OLD         Include 'inc/options/alternativeEnd.inc'
!!OLD      End If
    !
    ! *** store from temporary into final variables ***
    If (.Not.ERROR) Then
       vars   (iValue) = vars   (iTemp)
    End If
    !
    !D    Write (6,*) '   --> moduleCalibrate: SR calibrate before Call displayCalibrate '
    !
    ! *** display values ***
    If (.Not.ERROR) Then
       Call displayCalibrate
    End If
    !
    ! *** set "selected" observing mode & plot ***
    If (.Not.error) Then
       GV%observingMode     = OM%Cal
       GV%observingModePako = OMpako%Cal
       GV%omSystemName      = vars(iValue)%systemName 
       GV%notReadySWafterOM = .False.
       GV%notReadySecondaryRafterOM = .False.
       calibrateCommand     = line(1:lenc(line))
       Call analyzeCalibrate (errorA)
       !! TBD 2.0:        Call listSegmentList (errorA)
       Call plotCalibrate (errorP)
    End If
    !
    Return
  End Subroutine CALIBRATE
!!!
!!!
  Subroutine displayCalibrate
    !
    Include 'inc/variables/standardWorkingVariables.inc'
    !
    Character(len=24)  :: command
    !
    Call pako_message(seve%t,"PAKO",                                             &
         &  " module Calibrate, v 1.2.1  --> SR: displayCalibrate ")             ! trace execution
    !
    Include 'inc/display/commandDisplayCalibrate.inc'
    !
  End Subroutine displayCalibrate
!!!
!!!
  Subroutine analyzeCalibrate (errorA)

    Include 'inc/variables/standardWorkingVariables.inc'
    !
    Integer              :: nSubscans
    Character (len=12)   :: aUnit, sUnit
    !
    Call pako_message(seve%t,"PAKO",                                             &
         &  " module Calibrate, v 1.2.1  --> SR: analyzeCalibrate ")             ! trace execution
    !
    aUnit     = GV%angleUnitC
    sUnit     = GV%speedUnitC
    !
    errorA = .False.
    !
    segList(:) = segDefault
    !
    Call countSubscans(value=0)
    Call countSegments(value=0)
    !
    If (vars(iValue)%doGainImage) Then
       !
       Call countSubscans(ii)
       Call countSegments(jj)
       segList(ii)%newSubscan = .True.
       segList(ii)%ssNumber   =  ii
       segList(ii)%segNumber  =  jj
       segList(ii)%ssType     =  ss%ca
       segList(ii)%segType    =  seg%track
       segList(ii)%angleUnit  =  aUnit
       segList(ii)%speedUnit  =  sUnit
       segList(ii)%flagOn     =  .True.
       segList(ii)%flagRef    =  .False.
       segList(ii)%pStart%x   =  vars(iValue)%xOffsetRC
       segList(ii)%pStart%y   =  vars(iValue)%yOffsetRC
       segList(ii)%systemName =  vars(iValue)%systemName
       segList(ii)%tSegment   =  vars(iValue)%tCalibrate
       segList(ii)%tRecord    =  1.0
       segList(ii)%sideBand   =  sb%lsb
       !
       Call countSubscans(ii)
       Call countSegments(jj)
       segList(ii)%newSubscan = .True.
       segList(ii)%ssNumber   =  ii
       segList(ii)%segNumber  =  jj
       segList(ii)%ssType     =  ss%cc
       segList(ii)%segType    =  seg%track
       segList(ii)%angleUnit  =  aUnit
       segList(ii)%speedUnit  =  sUnit
       segList(ii)%flagOn     =  .True.
       segList(ii)%flagRef    =  .False.
       segList(ii)%pStart%x   =  vars(iValue)%xOffsetRC
       segList(ii)%pStart%y   =  vars(iValue)%yOffsetRC
       segList(ii)%systemName =  vars(iValue)%systemName
       segList(ii)%tSegment   =  vars(iValue)%tCalibrate
       segList(ii)%tRecord    =  1.0
       segList(ii)%sideBand   =  sb%lsb
       !
       Call countSubscans(ii)
       Call countSegments(jj)
       segList(ii)%newSubscan = .True.
       segList(ii)%ssNumber   =  ii
       segList(ii)%segNumber  =  jj
       segList(ii)%ssType     =  ss%ca
       segList(ii)%segType    =  seg%track
       segList(ii)%angleUnit  =  aUnit
       segList(ii)%speedUnit  =  sUnit
       segList(ii)%flagOn     =  .True.
       segList(ii)%flagRef    =  .False.
       segList(ii)%pStart%x   =  vars(iValue)%xOffsetRC
       segList(ii)%pStart%y   =  vars(iValue)%yOffsetRC
       segList(ii)%systemName =  vars(iValue)%systemName
       segList(ii)%tSegment   =  vars(iValue)%tCalibrate
       segList(ii)%tRecord    =  1.0
       segList(ii)%sideBand   =  sb%usb
       !
       Call countSubscans(ii)
       Call countSegments(jj)
       segList(ii)%newSubscan = .True.
       segList(ii)%ssNumber   =  ii
       segList(ii)%segNumber  =  jj
       segList(ii)%ssType     =  ss%cc
       segList(ii)%segType    =  seg%track
       segList(ii)%angleUnit  =  aUnit
       segList(ii)%speedUnit  =  sUnit
       segList(ii)%flagOn     =  .True.
       segList(ii)%flagRef    =  .False.
       segList(ii)%pStart%x   =  vars(iValue)%xOffsetRC
       segList(ii)%pStart%y   =  vars(iValue)%yOffsetRC
       segList(ii)%systemName =  vars(iValue)%systemName
       segList(ii)%tSegment   =  vars(iValue)%tCalibrate
       segList(ii)%tRecord    =  1.0
       segList(ii)%sideBand   =  sb%usb
       !
    Else
       !
       If (vars(iValue)%doSky) Then
          !
          Call countSubscans(ii)
          Call countSegments(jj)
          segList(ii)%newSubscan = .True.
          segList(ii)%ssNumber   =  ii
          segList(ii)%segNumber  =  jj
          segList(ii)%ssType     =  ss%cs
          segList(ii)%segType    =  seg%track
          segList(ii)%angleUnit  =  aUnit
          segList(ii)%speedUnit  =  sUnit
          segList(ii)%flagOn     =  .True.
          segList(ii)%flagRef    =  .False.
          segList(ii)%pStart%x   =  vars(iValue)%xOffsetRC
          segList(ii)%pStart%y   =  vars(iValue)%yOffsetRC
          segList(ii)%systemName =  vars(iValue)%systemName
          segList(ii)%tSegment   =  vars(iValue)%tCalibrate
          segList(ii)%tRecord    =  1.0
          !
          If (vars(iValue)%systemName.Eq.offs%pro) Then
             segList(ii)%updateDoppler = .True.
             segList(ii)%pDoppler      = segList(ii)%pStart
          Else
             segList(ii)%updateDoppler = .True.
             segList(ii)%pDoppler      = xyPointType(0.0,0.0)
          End If
          !
       End If
       !
       If (vars(iValue)%doAmbient) Then
          !
          Call countSubscans(ii)
          Call countSegments(jj)
          segList(ii)%newSubscan = .True.
          segList(ii)%ssNumber   =  ii
          segList(ii)%segNumber  =  jj
          segList(ii)%ssType     =  ss%ca
          segList(ii)%segType    =  seg%track
          segList(ii)%angleUnit  =  aUnit
          segList(ii)%speedUnit  =  sUnit
          segList(ii)%flagOn     =  .True.
          segList(ii)%flagRef    =  .False.
          segList(ii)%pStart%x   =  vars(iValue)%xOffsetRC
          segList(ii)%pStart%y   =  vars(iValue)%yOffsetRC
          segList(ii)%systemName =  vars(iValue)%systemName
          segList(ii)%tSegment   =  vars(iValue)%tCalibrate
          segList(ii)%tRecord    =  1.0
          !
       End If
       !
       If (vars(iValue)%doCold) Then
          !
          Call countSubscans(ii)
          Call countSegments(jj)
          segList(ii)%newSubscan = .True.
          segList(ii)%ssNumber   =  ii
          segList(ii)%segNumber  =  jj
          segList(ii)%ssType     =  ss%cc
          segList(ii)%segType    =  seg%track
          segList(ii)%angleUnit  =  aUnit
          segList(ii)%speedUnit  =  sUnit
          segList(ii)%flagOn     =  .True.
          segList(ii)%flagRef    =  .False.
          segList(ii)%pStart%x   =  vars(iValue)%xOffsetRC
          segList(ii)%pStart%y   =  vars(iValue)%yOffsetRC
          segList(ii)%systemName =  vars(iValue)%systemName
          segList(ii)%tSegment   =  vars(iValue)%tCalibrate
          segList(ii)%tRecord    =  1.0
          !
       End If
       !
       If (vars(iValue)%doGrid) Then                                      ! for polarization
          !
          Call countSubscans(ii)
          Call countSegments(jj)
          segList(ii)%newSubscan = .True.
          segList(ii)%ssNumber   =  ii
          segList(ii)%segNumber  =  jj
          segList(ii)%ssType     =  ss%cg
          segList(ii)%segType    =  seg%track
          segList(ii)%angleUnit  =  aUnit
          segList(ii)%speedUnit  =  sUnit
          segList(ii)%flagOn     =  .True.
          segList(ii)%flagRef    =  .False.
          segList(ii)%pStart%x   =  vars(iValue)%xOffsetRC
          segList(ii)%pStart%y   =  vars(iValue)%yOffsetRC
          segList(ii)%systemName =  vars(iValue)%systemName
          segList(ii)%tSegment   =  vars(iValue)%tCalibrate
          segList(ii)%tRecord    =  1.0
          !
       End If
       !
    End If
    !
    Call getCountSegments(nSegments)
    !
    Return 
    !
  End Subroutine analyzeCalibrate
!!!
!!!
  Subroutine plotCalibrate (errorP)
    !
    !**   Variables  for Plots   ***
    Include 'inc/variables/headerForPlotMethods.inc'
    !
    !**   standard working variables   ***
    Include 'inc/variables/standardWorkingVariables.inc'
    !
    errorP = .False.
    !
    Call configurePlots
    !
    Call plotCalSky(vars(iValue)%xOffsetRC, vars(iValue)%yOffsetRC,errorP)
    !
    Return
  End Subroutine plotCalibrate
!!!
!!!
  Subroutine saveCalibrate(programName,LINE,commandToSave,iUnit,ERROR)
    !
    ! *** Variables   ***
    Include 'inc/variables/headerForSaveMethods.inc'
    !
    Integer   ::   length
    !
    Call pako_message(seve%t,"PAKO",                                             &
         &  " module Calibrate, v 1.2.1  --> SR: saveCalibrate ")                ! trace execution
    !
    contC = contNN
    !
    ERROR = .False.
    !
    Include 'inc/commands/saveCommand.inc'
    !
    contC = contCC
    !
    Include 'inc/options/saveAmbient.inc'
    Include 'inc/options/saveCold.inc'
    !
    ! **  EMIR, HERA: no /gainIamge
!!OLD    Include 'inc/options/saveGainImage.inc'
    Include 'inc/options/saveGrid.inc'
!!OLD        include 'inc/options/saveFast.inc'
!!OLD        include 'inc/options/saveNull.inc'
    Include 'inc/options/saveSky.inc'
    Include 'inc/options/saveSystem.inc'
    !
    contC = contCN
    !
    Include 'inc/options/saveTcalibrate.inc'
!!OLD        include 'inc/options/saveTest.inc'
!!OLD        include 'inc/options/saveVariable.inc'
    !
    Write (iUnit,*) "!"
    !
    Return
  End Subroutine saveCalibrate
!!!
!!!
  Subroutine startCalibrate(programName,LINE,commandToSave,iUnit, ERROR)
    !
    ! *** Variables   ***
    Include 'inc/variables/headerForSaveMethods.inc'
    !
    Integer                 :: ii
    Character (len=lenCh)   :: valueC
    Character (len=lenLine) :: valueComment
    Character (len=lenLine) :: messageText
    Logical                 :: errorL, errorXML
    ! 
    Call pako_message(seve%t,"PAKO",                                              &
         &  " module Calibrate, v 1.2.1  --> SR: startCalibrate ")                ! trace execution
    !
    ERROR = .False.
    !
    Call pakoXMLsetOutputUnit(iunit=iunit)
    Call pakoXMLsetIndent(iIndent=2)
!!OLD   Call pakoXMLsetLevel(1)
    !
    Include 'inc/startXML/generalHead.inc'
    !
    Call writeXMLset(programName,LINE,commandToSave,                             &
         &           iUnit, ERROR)                                               !
    !
    Call pakoXMLwriteStartElement("RESOURCE","pakoScript",                       &
         &                         comment="save from pako",                     &
         &                         error=errorXML)                               !
    Call pakoXMLwriteStartElement("DESCRIPTION",                                 &
         &                         doCdata=.True.,                               &
         &                         error=errorXML)                               !
    !
    Include 'inc/startXML/savePakoScriptFirst.inc'
    !
    Call saveCalibrate    (programName,LINE,commandToSave, iUnit, errorL)
    !
    Call pakoXMLwriteEndElement("DESCRIPTION",                                   &
         &                         doCdata=.True.,                               &
         &                         error=errorXML)                               !
    Call pakoXMLwriteEndElement  ("RESOURCE","pakoScript",                       &
         &                         space="after",                                &
         &                         error=errorXML)                               !
    !
    Call writeXMLantenna(programName,LINE,commandToSave,                         &
         &         iUnit, ERROR)                                                 !
    !
    Call writeXMLreceiver(programName,LINE,commandToSave,                        &
         &         iUnit, ERROR)                                                 !
    !
    Call writeXMLbackend(programName,LINE,commandToSave,                         &
         &         iUnit, ERROR)                                                 !
    !
    Call writeXMLswTotalPower(programName,LINE,commandToSave,                    &
         &        iUnit, ERROR)                                                  !
    !
    Call writeXMLsource(programName,LINE,commandToSave,                          &
         &         iUnit, ERROR)                                                 !
    !
    Include 'inc/startXML/generalScanHead.inc'
    !
    !TBD: implement the same scheme for other observing modes
    !
    ! **  Observing Mode to XML
    If (gv%doXMLobservingMode) Then
       messageText = "writing observing mode in XML format"
       Call PakoMessage(priorityI,severityI,                                     &
               &           commandToSave,messageText)                            !
       Call writeXMLcalibrate(programName,LINE,commandToSave,                    &
         &         iUnit, ERROR)                                                 !
    End If
    !
    !!? TBD 2.0: 
!!$    !! NOTE: gain calibration not supported with current receivers (2012-06-21)
!!$    If (vars(iValue)%doGainImage) Then
!!$       Call writeXMLcalibrate(programName,LINE,commandToSave,                    &
!!$         &         iUnit, ERROR)
!!$    End If
    !
    ! **  subscan list to XML
    Call writeXMLsubscanList(programName,LINE,commandToSave,                     &
         &         iUnit, ERROR)                                                 !
    !   
    Include 'inc/startXML/generalTail.inc'
    !
    Return
  End Subroutine startCalibrate
!!!
!!!
  Subroutine writeXMLcalibrate(programName,LINE,commandToSave,iUnit,ERROR)
    !
    ! *** Variables   ***
    Include 'inc/variables/headerForSaveMethods.inc'
    !
    Integer                 :: ii, iMatch, nMatch, len1, len2
    Character (len=lenCh)   :: valueC, errorCode
    Character (len=lenLine) :: valueComment
    Logical                 :: errorL, errorM, errorXML
    !
    Call pako_message(seve%t,"PAKO",                                             &
         &  " module Calibrate, v 1.2.3  --> SR: writeXMLCalibrate 2014-10-24")  ! trace execution
    !
    ERROR = .False.
    !
    Call pakoXMLwriteStartElement("RESOURCE","observingMode",                    &
         &                         space ="before",                              &
         &                         error=errorXML)                               !
    !
    valueC = GV%observingMode
    Call pakoXMLwriteElement("PARAM","observingMode",valueC,                     &
         &                         dataType="char",                              &
         &                         error=errorXML)                               !
    !
    Include 'inc/startXML/optionAmbientXML.inc'
    Include 'inc/startXML/optionColdXML.inc'
    Include 'inc/startXML/optionSkyXML.inc'
    Include 'inc/startXML/optionSystemXML.inc'
    Include 'inc/startXML/optionTcalibrateXML.inc'
    Include 'inc/startXML/optionGainImageXML.inc'
    Include 'inc/startXML/optionGridXML.inc'
    !
    Include 'inc/startXML/annotationsXML.inc'
    !
    Call pakoXMLwriteEndElement("RESOURCE","observingMode",                      &
         &                         error=errorXML)                               !
    !
    Return
  End Subroutine writeXMLcalibrate
!!!
!!!
End Module modulePakoCalibrate





