!************************************************************************
! A Subroutine of Main, scanning the PDB file, to determine the         *
! dimension of the array                                                *
!************************************************************************

       Subroutine ScanPDB(PDBid, MinModel, MaxModel, MinChain, MaxChain, MinResidue, MaxResidue, MinAtom, MaxAtom, MaxHelix, MaxSheet, MaxStrand, MaxTurn, PDBerror, itrt)
       
       Implicit None
 
! ---- Variables : -------------------------------------------------------------- !       
       Character*4 PDBid
       
       Integer    PDBerror  ! Error Code (process PDBerror at line 777; PDBerror=100 : no error)
       
       Integer    MinModel, MinChain, MinResidue, MinAtom  ! The initial Min value is set to an extreme big value
       Integer    MaxModel, MaxChain, MaxResidue, MaxAtom  ! The initial Max value is set to an extreme small value
       
       Integer    MaxHelix, MaxSheet, MaxStrand, MaxTurn
       Integer    itrt    ! The iteration number
       
       Integer    i, j, k
! ---- Variables : -------------------------------------------------------------- !       
       LOGICAL      PDBexist
       Integer ::   aaflag=0     ! indicate the Amino Acids(1) or Nucleic Acids(2), or Null (0)
       Integer      ICA,  D1INT, D2INT, Imodel, Ichain, Iresidue, Iatom
       Real         XXX, YYY, ZZZ, R1, BBB
       Integer      AAA
       Character*6  DUMMY6
       Character*4  ATNAME
       Character*3  DUMMY3 
       Character*80 DUMMY80 
       Character*1  A1
       
       Integer      ChainIndex ! function, return a number for a given chain ID
       
! ---- Variables : -------------------------------------------------------------- !       
       Character    CHead*6, CMark*3, CLine*80
       Integer      RecordType ! each section in PDB file is assigned a RecordType
       
       Character*6  SedName        ! Secondary Structure Head Name
       Character*3  SedID          ! Secondary Structure ID 
       
       Integer      serNum         ! Serial number of the helix.
       
       Character*3  initResName    ! Name of the intial residue.
       Character*1  initChainID    ! Chain identifier for the chain containing this helix.
       Integer      initSeqNum     ! Sequence number of the initial residue.
       Character*1  initICode      ! Insertion code of the initial residue.
       
       Character*3  endResName     ! Name of the terminal residue.
       Character*1  endChainID     ! Chain identifier for the chain containing this helix.
       Integer      strand         ! Strand number which starts at 1 for each strand within a sheet and increases by one.      
       Integer      endSeqNum      ! Sequence number of the terminal residue.
       Character*1  endICode       ! Insertion code of the terminal residue.
       
       Integer      helixClass     ! Helix class 
       Character*30 comment        ! Comment about this helix.
       Integer      length         ! Length of this helix.
       
       Integer      numStrand      ! Number of Strands
       Integer      sense          ! Sense of strand with respect to previous strand in the sheet. 0 if first strand, 1 if parallel, -1 if anti-parallel.
       Character*30 SheetReg       ! Registration
       
       Integer      numSheet       ! The sheet number
       Integer      SheetIndex     ! Fuction, return a Sheet number, for a given SheetID
       
       Character*3  SheetName(999) ! The database for storing the sheet ID
           
	   Character    ACE*2 ! the string will be stored here 
! ------------------------------------------------------------------------------- !

! =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-! 
!                     + + Scan the Coordinates Part of PDB file + +                       !
! =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-! 

       MinModel=9999 ! The initial Min value is set to an extreme big value
       MaxModel=-999 ! The initial Max value is set to an extreme small value
       
       MinChain=9999
       MaxChain=-999
       
       MinResidue=9999
       MaxResidue=-999
       
       MinAtom=1
       MaxAtom=100
       
       
!       INQUIRE (FILE=PDBid//'_Itr'//ACE(itrt-1,2)//'.pdb', EXIST=PDBexist) 
       INQUIRE (FILE=PDBid//'.pdb', EXIST=PDBexist) 
       
       If( (PDBexist==.False.)) Then
          PDBerror=110 ! pdbid, ' :  PDB file does not exists!'
          goto 777
       EndIf
       
!       Open(10, FILE=PDBid//'_Itr'//ACE(itrt-1,2)//'.pdb')
       Open(10, FILE=PDBid//'.pdb')

       Imodel=0 ! Attention : Here I set Imodel=0, do not use Imodel in the next loop !!! some pdb files do not have model number.
       
210	   DUMMY6 = '      '
 	   READ(10, '(A)', ERR=230, END=230 ) DUMMY6

       If(DUMMY6(1:5)=='MODEL') Then !---------------Deal with Model 
            Backspace(10)
            Read(10,*) DUMMY6, D1INT
            Imodel=D1INT
            If(Imodel<MinModel) MinModel=Imodel
            If(Imodel>MaxModel) MaxModel=Imodel

       EndIf !-----------------------------------Deal with Model 
        
!       IF( DUMMY6=='END   ' )  GOTO 230 !===============End of File, jump to 230
        
       IF(DUMMY6(1:4).NE.'ATOM')  GOTO 210
       
	   BACKSPACE(10)
	   
       READ(10,55) DUMMY6,D1INT,ATNAME,DUMMY3,A1,D2INT,XXX,YYY,ZZZ,R1,BBB
              
       aaflag=0
       !===========[Amino Acids]============
       If( (DUMMY3=='ALA').OR.(DUMMY3=='ARG').OR.(DUMMY3=='ASN').OR.(DUMMY3=='ASP').OR.(DUMMY3=='ASX') ) aaflag=1
       If( (DUMMY3=='CYS').OR.(DUMMY3=='GLN').OR.(DUMMY3=='GLU').OR.(DUMMY3=='GLX').OR.(DUMMY3=='GLY') ) aaflag=1
       If( (DUMMY3=='HIS').OR.(DUMMY3=='ILE').OR.(DUMMY3=='LEU').OR.(DUMMY3=='LYS').OR.(DUMMY3=='MET') ) aaflag=1
       If( (DUMMY3=='PHE').OR.(DUMMY3=='PRO').OR.(DUMMY3=='SER').OR.(DUMMY3=='THR').OR.(DUMMY3=='TRP') ) aaflag=1
       If( (DUMMY3=='TYR').OR.(DUMMY3=='VAL')                                                          ) aaflag=1
      
      
       !===========[Nucleic Acids]============
       If( (DUMMY3=='  A').OR.(DUMMY3==' +A').OR.(DUMMY3=='  C').OR.(DUMMY3==' +C') ) aaflag=2
       If( (DUMMY3=='  G').OR.(DUMMY3==' +G').OR.(DUMMY3=='  I').OR.(DUMMY3==' +I') ) aaflag=2
       If( (DUMMY3=='  T').OR.(DUMMY3==' +T').OR.(DUMMY3=='  U').OR.(DUMMY3==' +U') ) aaflag=2
       If( (DUMMY3=='  T').OR.(DUMMY3==' +T').OR.(DUMMY3=='  U').OR.(DUMMY3==' +U') ) aaflag=2
                                           

	   If( (aaflag==1).OR.(aaflag==2) ) Then

	        Iresidue=D2INT
	        If( Iresidue<MinResidue) MinResidue=Iresidue
	        If( Iresidue>MaxResidue) MaxResidue=Iresidue
        	
   	        Ichain=ChainIndex(A1)
   	        If(Ichain==0) Then
   	            PDBerror=103 ! 'Error: there is something wrong with the Chain name in the PDB file!'
   	            Goto 777
   	        EndIf
           	
   	        If( Ichain<MinChain ) MinChain=Ichain 
   	        If( Ichain>MaxChain ) MaxChain=Ichain 
   	        

       EndIf ! If( (aaflag==1).OR.(aaflag==2) ) 
	       
	   GOTO 210
	
230	   Continue
       Close(10)    !  FILE=PDBid//'_Itr'//ACE(itrt-1,2)//'.pdb'  
       
       If( Imodel==0 ) Then
          MinModel=1
          MaxModel=1
       EndIF
       
55	   FORMAT(A6,I5,1X,A4,1X,A3,1X,A1,I4,4X,3F8.3,2F6.2)


! =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-! 
!                         + + Scan the Head Part of PDB file + +                          !
! =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-! 
       MaxHelix  = 0
       MaxSheet  = 0
       MaxStrand = 0
       MaxTurn   = 0

       Do i=1, 999
          SheetName(i)='***'
       Enddo

!       Open(12, FILE=PDBid//'_Itr'//ACE(itrt-1,2)//'.pdb')  
       Open(12, FILE=PDBid//'.pdb')  
       

610	   READ(12,'(A6,1x,A3)',END=660) CHead, CMark

       IF( (CHead=='ATOM  ').OR.(CHead=='END   ').OR.(CHead=='ENDMDL') ) GOTO 660 !============End of File, jump to 660
       
       RecordType=0
       If ( (CHead=='HEADER').OR.(CHead=='TITLE ')                                            ) RecordType=1 ! Title Section
       If ( (CHead=='REMARK').AND.( CMark=='350' )                                            ) RecordType=2 ! /REMARK 350   BIOMT* **** ..../    
       If ( (CHead=='DBREF ').OR.(CHead=='SEQADV').OR.(CHead=='SEQRES').OR.(CHead=='MODRES')  ) RecordType=3 ! Primary Structure Section
       If ( (CHead=='HET   ').OR.(CHead=='HETNAM').OR.(CHead=='HETSYN').OR.(CHead=='FORMUL')  ) RecordType=4 ! Heterogen Section
       If ( (CHead=='HELIX ').OR.(CHead=='SHEET ').OR.(CHead=='TURN  ')                       ) RecordType=5 ! Secondary Structure Section
       If ( (CHead=='SSBOND').OR.(CHead=='LINK  ').OR.(CHead=='HYDBND').OR.(CHead=='SLTBRG')  ) RecordType=6 ! Connectivity Annotation Section
       If ( (CHead=='CISPEP')                                                                 ) RecordType=6 ! Connectivity Annotation Section
       If ( (CHead=='SITE  ').OR.(CHead=='CONECT').OR.(CHead=='TER   ').OR.(CHead=='SIGATM')  ) RecordType=7 ! Miscellaneous Features Section
       If ( (CHead=='ANISOU').OR.(CHead=='SIGUIJ')                                            ) RecordType=7 ! Miscellaneous Features Section
       
        
       If( RecordType==5 ) Then    !+++++++++++++++++  Secondary Structure 
            
            If(CHead=='HELIX ') Then ! *************Helix
            
               Backspace(12)
               Read(12,66) SedName, serNum,  SedID,  initResName, initChainID, initSeqNum, initICode, endResName, endChainID, endSeqNum, endICode, helixClass, comment,  length 
66             Format(      A6,       I4, 1x, A3,  1x,   A3,    1x,   A1,    1x,   I4,         A1,  1x,   A3,   1x,   A1,   1x,   I4,      A1,         I2,       A30, 1x, I5   )               
!                           1-6,    7-10, 11,12-14,15,  16-18,  19,   20,    21,  22-25,       26,  27,  28-30, 31,   32,   33,  34-37,    38,        39-40,    41-70,71, 72-76 
               If(serNum>MaxHelix) MaxHelix=serNum
                              
            EndIF
            
            If(CHead=='SHEET ') Then ! *************SHEET
            
               Backspace(12)
               Read(12,77) SedName, strand,  SedID,  numStrand, initResName, initChainID, initSeqNum, initICode, endResName, endChainID, endSeqNum, endICode, sense, SheetReg
77             Format(      A6,       I4, 1x, A3,       I2,   1x,   A3,    1x,   A1,         I4,         A1,  1x,    A3,   1x,   A1,        I4,        A1,     I2,       A30   )               
!                           1-6,     7-10,11,12-14,    15-16, 17, 18-20,   21,   22,        23-26,       27,  28,   29-31, 32,   33,       34-37,      38,    39-40,    41-70 
               
               numSheet = SheetIndex(SedID,999,SheetName)
               
               If(numSheet>MaxSheet)   MaxSheet=numSheet
               If(numStrand>MaxStrand) MaxStrand=numStrand
               
            EndIF            
            
            If(CHead=='TURN  ') Then ! *************TURN
            
               Backspace(12)
               Read(12,88) SedName, serNum,   SedID,  initResName, initChainID, initSeqNum, initICode, endResName, endChainID, endSeqNum, endICode,    comment 
88             Format(       A6,      I4, 1x,  A3,  1x,   A3,    1x,   A1,         I4,         A1,   1x,   A3,   1x,   A1,        I4,       A1,    4x,   A30  )               
!                           1-6,     7-10,11,12-14, 15, 16-18,   19,   20,        21-24,       25,   26,  27-29, 30,   31,       32-35,     36,   37-40, 41-70 

               If(serNum>MaxTurn) MaxTurn=serNum
                              
            EndIF            
            
            
       EndIf ! If( RecordType==5 ) 
          

       
       Goto 610

660    Continue       
       Close(12) ! FILE=PDBid//'_Itr'//ACE(itrt-1,2)//'.pdb'     
              
       
777    If(PDBerror==100) Then
          Continue
          
       ElseIF(PDBerror==103) Then       
          Write(*,*) 'Error: there is something wrong with the Chain Name [A1] : ', A1
          Stop
       
       ElseIF(PDBerror==104) Then       
          Write(*,*) 'Error: This atom name is not in the list: [ATNAME] : ',  ATNAME
          Stop

       ElseIF(PDBerror==110) Then       
          Write(*,*) 'Error: PDB file does not exists! [PDBid] : ', PDBid
          Stop
          
       EndIf
       
       Write(*,'(A)') '_______________________________________________________________'
       Write(*,'(A,A4,A)') 'Reading File : ', PDBid, '.pdb'
       Write(*,*) '                                                           '
       Write(*,'(A,I5,A,I5)') 'Model   Range  : ', MinModel,  ' to ', MaxModel
       Write(*,'(A,I5,A,I5)') 'Chain   Range  : ', MinChain,  ' to ', MaxChain
       Write(*,'(A,I5,A,I5)') 'Residue Range  : ', MinResidue,' to ', MaxResidue
       Write(*,*) '                                                           '
       Write(*,'(A,I5)')      'Helix   Number : ', MaxHelix
       Write(*,'(A,I5)')      'Sheet   Number : ', MaxSheet
       Write(*,'(A,I5)')      'Strand  Number : ', MaxStrand
       Write(*,'(A,I5)')      'Turn    Number : ', MaxTurn
       Write(*,'(A)') '_______________________________________________________________'
       
       Write(*,*) '                                                           '       
       Write(*,'(A)') 'Initializing the Array . . . . . .  '       
! =====E==N===D================================================================== !
       Return
       End    

