MODULE TPCdata USE f90_kind USE IOunits USE Threshold USE Space PRIVATE ! fill information ! ReadChannel(iPad) ! FillSignal(iPad,signal,time) ! VoidSignal(iPad) PUBLIC :: ReadChannel,FillSignal,VoidSignal ! get layout information ! iGroup = PadGroup(iPad) ! iRow = PadRow(iPad) ! pad = PadLocation(iPad) PUBLIC :: PadGroup,PadRow,PadLocation ! get signal information ! getSignal(iPad,Amplitude,T0) ! getSignalGroup(iGroup,Amplitude,T0) ! getSignalRow(iRow,Amplitude,T0) ! GmaxSignalRow(iRow,iGmax,Amplitude,T0) PUBLIC :: GetSignal,GetSignalGroup,GetSignalRow,GmaxSignalRow ! get position information ! Neighbour(Middle,Left,Right) PUBLIC :: Neighbour ! AllocArrays() PUBLIC :: AllocArrays ! you might have to change TYPE of location ! and the return type of PadLocation TYPE,PRIVATE :: Pad_type INTEGER :: group , row REAL :: amplitude , T0 TYPE(Rectangle_type) :: location ! TYPE(Grid_type) :: location END TYPE Pad_type ! variables INTEGER,PUBLIC,SAVE :: nPads,nGroups,nRows,nTbin INTEGER,PUBLIC,SAVE,ALLOCATABLE,DIMENSION(:) :: & nPadsinGroup, & ! nPadsinGroup(nGroups) nPadsinRow, & ! nPadsinRow(nRows) nGroupsinRow ! nGroupsinRow(nRows) INTEGER,PUBLIC,SAVE :: maxPinGroup, maxPinRow, maxGinRow INTEGER,PUBLIC,SAVE,ALLOCATABLE,DIMENSION(:,:) :: & iPadofGroup, & ! iPadofGroup(maxPinGroup,nGroups) iPadofRow, & ! iPadofRow(maxPinRow,nRows) iGroupofRow ! iGroupofRow(maxGinRow,nRows) ! data for one event: INTEGER,PUBLIC,SAVE :: RunNumber,EventNumber,Time INTEGER,PUBLIC,SAVE,ALLOCATABLE,DIMENSION(:) :: & nTbGroup ! nTbGroup(nGroups) = actual nTbin for Group ! INTEGER(KIND=int16),PUBLIC,SAVE,ALLOCATABLE,DIMENSION(:,:) :: & INTEGER,PUBLIC,SAVE,ALLOCATABLE,DIMENSION(:,:) :: & IADC ! IADC(nTbin,nGroups) = plain data REAL,PUBLIC,SAVE,ALLOCATABLE,DIMENSION(:,:) :: & ADC ! ADC(nTbin,nGroups) = pedestal subtracted ! Monte Carlo Tree: REAL,PUBLIC,SAVE :: MCx0=0.0,MCz0=0.0,MCphi=0.0,MCtheta=0.0 TYPE(Pad_type),PRIVATE,SAVE,ALLOCATABLE,DIMENSION(:) :: info ! info(nPads) ! number of bitmaps for Grid_type INTEGER,PUBLIC,SAVE :: NumMaps=0 ! **************************************************************** PRIVATE :: ReadPad,ReadRect,ReadGrid INTERFACE ReadPad MODULE PROCEDURE ReadRect,ReadGrid END INTERFACE ! **************************************************************** CONTAINS SUBROUTINE AllocArrays() INTEGER :: IERR ! will be allocated in ReadHeader ALLOCATE ( nTbGroup(0) ) ALLOCATE ( IADC(0,0) ) ALLOCATE ( ADC(0,0) ) ALLOCATE ( info(nPads),STAT=IERR ) IF( IERR /= 0 )THEN WRITE(UNIT=IOErr,FMT=*) "ERROR, AllocArrays: cant allocate info" STOP ENDIF ALLOCATE ( nPadsinGroup(nGroups),STAT=IERR ) IF( IERR /= 0 )THEN WRITE(UNIT=IOErr,FMT=*) "ERROR, AllocArrays: cant allocate nPadsinGroup" STOP ENDIF ALLOCATE ( nPadsinRow(nRows),STAT=IERR ) IF( IERR /= 0 )THEN WRITE(UNIT=IOErr,FMT=*) "ERROR, AllocArrays: cant allocate nPadsinRow" STOP ENDIF ALLOCATE ( nGroupsinRow(nRows),STAT=IERR ) IF( IERR /= 0 )THEN WRITE(UNIT=IOErr,FMT=*) "ERROR, AllocArrays: cant allocate nGroupsinRow" STOP ENDIF ALLOCATE ( iPadofGroup(maxPinGroup,nGroups),STAT=IERR ) IF( IERR /= 0 )THEN WRITE(UNIT=IOErr,FMT=*) "ERROR, AllocArrays: cant allocate iPadofGroup" STOP ENDIF ALLOCATE ( iPadofRow(maxPinRow,nRows),STAT=IERR ) IF( IERR /= 0 )THEN WRITE(UNIT=IOErr,FMT=*) "ERROR, AllocArrays: cant allocate iPadofRow" STOP ENDIF ALLOCATE ( iGroupofRow(maxGinRow,nRows),STAT=IERR ) IF( IERR /= 0 )THEN WRITE(UNIT=IOErr,FMT=*) "ERROR, AllocArrays: cant allocate iGroupofRow" STOP ENDIF END SUBROUTINE AllocArrays SUBROUTINE ReadChannel(iPad) INTEGER,INTENT(IN) :: iPad CALL ReadPad(iPad,info(iPad)%location) END SUBROUTINE ReadChannel SUBROUTINE ReadRect(iPad,padloc) INTEGER,INTENT(IN) :: iPad TYPE(Rectangle_type),INTENT(OUT) :: padloc INTEGER :: iP,iGroup,iRow,ios REAL(KIND=spPrec) :: cX,cY,sX,sY READ(UNIT=IOLayout,FMT=*,IOSTAT=ios)iP,iGroup,iRow,cX,cY,sX,sY IF( ios/=0 )THEN WRITE(UNIT=IOErr,FMT=*) "ERROR: reading pad",iPad STOP ENDIF IF( iPad /=iP )THEN PRINT*,iPad,iP WRITE(UNIT=IOErr,FMT=*) "ERROR: Please give the pads in order from 1 to",nPads STOP ENDIF IF( iGroup<1 .OR. iGroup>nGroups )THEN WRITE(UNIT=IOErr,FMT=*) "ERROR: Please give groups in the range 1 to",nGroups STOP ENDIF IF( iRow<1 .OR. iRow>nRows )THEN WRITE(UNIT=IOErr,FMT=*) "ERROR: Please give rows in the range 1 to",nRows STOP ENDIF info(iPad)%group = iGroup info(iPad)%row = iRow CALL FillLoc(cX,cY,sX,sY,padloc) END SUBROUTINE ReadRect SUBROUTINE ReadGrid(iPad,padloc) INTEGER,INTENT(IN) :: iPad TYPE(Grid_type),INTENT(OUT) :: padloc INTEGER :: iP,iGroup,iRow,mapNumber,ios REAL(KIND=spPrec) :: cX,cY,sX,sY READ(UNIT=IOLayout,FMT=*,IOSTAT=ios)iP,iGroup,iRow,cX,cY,sX,sY,mapNumber IF( ios/=0 )THEN WRITE(UNIT=IOErr,FMT=*) "ERROR: reading pad",iPad STOP ENDIF IOS = 0 IF( iPad /=iP )THEN PRINT*,iPad,iP PRINT*,"ERROR: Please give the pads in order from 1 to",nPads IOS = 1 ENDIF IF( iGroup<1 .OR. iGroup>nGroups )THEN PRINT*,"ERROR: Please give groups in the range 1 to",nGroups PRINT*,"If the data have group numbers from 0 to N-1, group 0 will be renamed to N" PRINT*,"Please change your layout accordingly." IOS = 1 ENDIF IF( iRow<1 .OR. iRow>nRows )THEN PRINT*,"ERROR: Please give rows in the range 1 to",nRows IOS = 1 ENDIF IF( IOS /= 0 ) STOP info(iPad)%group = iGroup info(iPad)%row = iRow NumMaps = max(NumMaps,mapNumber) CALL FillLoc(cX,cY,sX,sY,mapNumber,padloc) END SUBROUTINE ReadGrid SUBROUTINE VoidSignal(iPad) INTEGER,INTENT(IN) :: iPad info(iPad)%amplitude = -1.0 info(iPad)%T0 = 1.0 END SUBROUTINE VoidSignal SUBROUTINE FillSignal(iPad,signal,time) INTEGER,INTENT(IN) :: iPad REAL,INTENT(IN) :: time,signal IF( signal >= minSignal )THEN info(iPad)%amplitude = signal IF( nTbin==0 )THEN ! DenseData info(iPad)%T0 = time ELSEIF( time < 1.0 )THEN info(iPad)%T0 = 1.0 ! ELSEIF( time > REAL(nTbin) )THEN ! info(iPad)%T0 = nTbin ELSE info(iPad)%T0 = time ENDIF ELSE info(iPad)%amplitude = 0.0 info(iPad)%T0 = 1.0 ENDIF END SUBROUTINE FillSignal PURE FUNCTION PadGroup(iPad) Result(iGroup) INTEGER,INTENT(IN) :: iPad INTEGER :: iGroup iGroup = info(iPad)%group END FUNCTION PadGroup PURE FUNCTION PadRow(iPad) Result(iRow) INTEGER,INTENT(IN) :: iPad INTEGER :: iRow iRow = info(iPad)%row END FUNCTION PadRow PURE FUNCTION PadLocation(iPad) RESULT(PLoc) INTEGER,INTENT(IN) :: iPad TYPE(Rectangle_type) :: PLoc ! TYPE(Grid_type) :: PLoc PLoc = info(iPad)%location END FUNCTION PadLocation PURE SUBROUTINE getSignal(iPad,Amplitude,T0) INTEGER,INTENT(IN) :: iPad REAL, INTENT(OUT) :: Amplitude,T0 IF( iPad < 1 .OR. iPad > nPads )THEN Amplitude = -2.0 T0 = 1.0 RETURN ENDIF Amplitude = info(iPad)%amplitude T0 = info(iPad)%T0 END SUBROUTINE getSignal PURE SUBROUTINE GetSignalGroup(iGroup,Amplitude,T0) ! return the amplitude and T0 of a group ! pads in a group might have different amplitudes !(if they are in different rows), get the maximum amplitude INTEGER,INTENT(IN) :: iGroup REAL, INTENT(OUT) :: Amplitude,T0 REAL :: ampl,ap,time,t INTEGER :: i,iPad IF( iGroup < 1 .OR. iGroup > nGroups )THEN Amplitude = -2.0 T0 = 1.0 RETURN ENDIF ampl = -10.0 DO i=1,nPadsinGroup(iGroup) iPad = iPadofGroup(i,iGroup) CALL GetSignal(iPad,ap,t) IF( ap > ampl )THEN ampl = ap time = t ENDIF ENDDO Amplitude = ampl T0 = time END SUBROUTINE GetSignalGroup PURE SUBROUTINE GetSignalRow(iRow,Amplitude,T0) ! returns the sum of amplitudes in one row and the ! amplitude weighted T0 INTEGER,INTENT(IN) :: iRow REAL, INTENT(OUT) :: Amplitude,T0 REAL :: aa,ampl,tamp,ap,t,maxA,maxT INTEGER :: iP,iPad,iG,iGroup ampl = 0.0 aa = 0.0 tamp = 0.0 DO iG = 1,nGroupsinRow(iRow) iGroup = iGroupofRow(iG,iRow) maxA = -10.0 maxT = 1.0 DO iP = 1,nPadsinGroup(iGroup) iPad = iPadofGroup(iP,iGroup) CALL GetSignal(iPad,ap,t) IF( info(iPad)%row == iRow .AND. ap>maxA) THEN maxA = ap maxT = t ENDIF ENDDO IF( maxA>1.0 )THEN ampl = ampl + maxA aa = aa + maxA*maxA tamp = tamp + maxA*maxA*maxT ENDIF ENDDO Amplitude = ampl IF( aa > 0.0 )THEN T0 = tamp/aa ELSE T0 = 1.0 ENDIF END SUBROUTINE GetSignalRow PURE SUBROUTINE GmaxSignalRow(iRow,iGmaxAmpl,maxAmpl,T0) ! find group with largest signal in this row INTEGER,INTENT(IN) :: iRow INTEGER,INTENT(OUT) :: iGmaxAmpl REAL,INTENT(OUT) :: maxAmpl,T0 INTEGER :: iGmax,iG,iGroup,iP,iPad REAL :: ampl,T,max,Time max = -10.0 Time = 0.0 iGmax = -1 DO iG = 1,nGroupsinRow(iRow) iGroup = iGroupofRow(iG,iRow) DO iP = 1,nPadsinGroup(iGroup) iPad = iPadofGroup(iP,iGroup) CALL GetSignal(iPad,ampl,T) IF( ampl > max .AND. info(iPad)%row == iRow ) THEN max = ampl Time = T iGmax = iGroup ENDIF ENDDO ENDDO iGmaxAmpl = iGmax maxAmpl = max T0 = Time END SUBROUTINE GmaxSignalRow ! <<<< GET AMPLITUDE AND T0 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ! geometry routines ************************************************ PURE SUBROUTINE Neighbour(Middle,Left,Right) INTEGER,INTENT(IN) :: Middle INTEGER,INTENT(OUT) :: Left,Right INTEGER :: iRow,iP,iPad REAL(KIND=spPrec) :: XM,DX,Lmin,Rmin iRow = PadRow(Middle) XM = Pitch(getCentre(PadLocation(Middle))) Left = 0 Right = 0 Lmin = 1.0E6 Rmin = 1.0E6 DO iP=1,nPadsinRow(iRow) iPad = iPadofRow(iP,iRow) IF( iPad == Middle )cycle DX = XM - Pitch(getCentre(PadLocation(iPad))) IF( DX < 0.0 )THEN IF( ABS(DX) < Lmin )THEN Lmin = ABS(DX) Left = iPad ENDIF ELSE IF( DX < Rmin )THEN Rmin = DX Right = iPad ENDIF ENDIF ENDDO END SUBROUTINE Neighbour END MODULE TPCdata