In the First Daysection of the Workbook we ran an IDA session where we looked at and plotted the inverse transverse momentum of charged particles, using "PEEK _PHCHRG(1).HLXPAR(2)" and "HIST PHCHRG%(HLXPAR(2)) FROM 0 TO 10" commands. At that time we had to take it on faith that we were plotting the appropriate quantities and accessing them correctly. In this section we will look more closely at the PHCHRG bank in an attempt to understand how to extract the information we need from it and other jazelle banks.
>
eve ducssearch:phchrg.template
where ducssearch
is one of the DUCS logical names we learned
about in the previous section of the Workbook.
!---------------------------------------------------------------------*\ !==> Mini DST bank containing track information | !----------------------------------------------------------------------| ! KEYWORDS: MINI-DST | !*--------------------------------------------------------------------*| ! | ! OWNER: Homer CO-OWNER: Hildreth | ! SECTION: DST FILE: PHCHRG TEMPLATE | ! | ! Version Name Date Explanation of Changes | ! ------- ------------ ----------- ----------------------------------- | ! 0.00 Strauss 12 Oct 1993 Creation from PHTKSUM | ! 0.01 Strauss 06 Jan 1994 First Correct released version | ! 0.02 Homer 05 Mar 1994 added de/dx word | ! 0.03 Richard 06 Oct 1994 change dE/dx to I*4 | !*--------------------------------------------------------------------*/ Bank PHCHRG Context=DST DEMAND_ZERO Maxid=1000 "Useful tkpars/tk"This is the template header which describes the bank. All templates must have headers. All but the last line of the header are enclosed in comment characters, however SLD's code management software needs to have this information. The information within the comment characters is as follows:
After the commented section of the header, we have the bank description line. It defines:
You should see a line that looks something like:
REAL HLXPAR(6) " * track parameters and error matrix * "This tells us that HLXPAR is a real array of six elements. The "*" in the description tell us to look for the definition as a footnote. Somewhere near the bottom of the template you should find something that looks like:
! NOTE 3: ! ! HLXPAR(1) = phi ! HLXPAR(2) = 1/pt ! HLXPAR(3) = tan(lambda) ! HLXPAR(4) = x ! HLXPAR(5) = y ! HLXPAR(6) = z ! ! note: HLXPAR(4-6) are reported as (x,y,z) for convenience. the ! error matrix DHLXPAR(1-15) has elements which correspond to ! parameter 4 = TSI and parameter 5 = ETA, two distances to a ! given point defined by: ! TSI = TN dot DELTA ! ETA = TQ dot DELTA ! ! where DELTA = (x-x0, y-y0, z-z0) {(x0,y0,z0) = given origin} ! TN = PHAT cross TM (PHAT = momentum unit vector) ! (TM = mag field unit vector) ! TQ = (1/(1-(PHAT dot TM)**2) * (TM - (PHAT dot TM)PHAT) ! ! to convert HLXPAR(1-3) to a momentum vector (PX,PY,PZ): ! ! PTOT = pt/cos(lambda) ! PX = PTOT * cos(lambda) * cos(phi) ! PY = PTOT * cos(lambda) * sin(phi) ! PZ = PTOT * sin(lambda)So we see that HLXPAR(2) is the inverse transverse momentum. Now take a moment and study the rest of the data available in this bank.
To do this just type "IDA" at the VMS prompt. At the Ida prompt type:
Ida> IndexYou will get a list of banks currently in IDA memory. In the first column you will see the family name, in the second column the number of banks in this family, in the third column the context and in the fourth column a title or description. None of these are that interesting since they are Ida's default or automatically loaded banks. Add A PHCHRG bank to memory
To do this type:
Ida> ADD PHCHRG Ida> INDEXNow we see there is 1 PHCHRG bank in memory. Examine its contents.
Ida> PEEK PHCHRGNote everything is Zero except ESTAT and MUSTAT. This makes sense since we are not looking at real data, all we did was load the bank into memory. There was a DEMAND ZERO at top of the PHCHRG template which clears all undeclared entries, but the values of estat and mustat where declared thus are non zero.
Ida> POKE PHCHRG.IMPACT=0.2 Ida> POKE PHCHRG.HLXPAR(2)=0.1 Ida> PEEK PHCHRGSo we see that we were able to set the values of the bank element with the POKE command.
Let us now see how bank IDs come into play by adding another bank.
Add another PHCHRG bank as above:
Ida> ADD PHCHRG Ida> INDEXNote when we typed index we saw the number of PHCHRG banks was 2.
Ida> PEEK PHCHRGNotice the top line says:
Family: PHCHRG ID: 2 Template Version: 0.00So we examined the bank with ID=2, and we notice that HLXPAR(2) and IMPACT =0. The bank we changed the values in is ID = 1.
Ida> PEEK PHCHRG(1) Ida> PEEK PHCHRG(2)We see we can differentiate between the two banks by specifying the ID.
Ida> POINTER PC --> PHCHRGDefines a pointer that points to the first bank in the family. We have the ability to set the pointer to point to whichever bank we desire. In order to do this, let us add one more bank and, for accounting purposes, let us set the charge equal to the bank ID.
Ida> ADD PHCHRG Ida> POKE PHCHRG(1).CHARGE=1 Ida> POKE PHCHRG(2).CHARGE=2 Ida> POKE PHCHRG(3).CHARGE=3Currently we have our pointer pointing at the first bank in the family. However we have the ability to change which bank the pointer points to.
Ida> TYPE PC%(charge) Ida> PC=_PHCHRG(LAST) Ida> TYPE PC%(charge) Ida> PC=_PHCHRG(2) Ida> TYPE PC%(charge) Ida> PC=_PHCHRG Ida> TYPE PC%(charge)It is not always necessary to declare a pointer explicitly. The underscore notation "_BANK( )" is sufficient although sometimes making code harder for others to read. Using the underscore notation:
Ida> TYPE BANKCNT(PC)Note when using bankcnt we must have the pointer pointing to the first bank in the family. If it is not, it will only count the bank it is pointing at and the banks following that one. Therefore it is usually safer to use the command as follows.
Ida> TYPE BANKCNT(_PHCHRG)
If we wanted to loop over the banks we could do something like:
Ida> N=BANKCNT(_PHCHRG) Ida> DO I = 1 TO N Ida> PC=_PHCHRG(I) Ida> TYPE PC%(CHARGE) Ida> ENDDONote that after you type the do line you should see
%IDA-I-INFO Begin implicit definition
and ida does not do actually run the commands until you specify the end of the loop with the line "enddo." The format of an ida DO LOOP will be discussed in detail in a later section of this workbook.
Because so much of IDA code involves looping over banks, IDA has a special construction just for this purpose. You do not have to use it, the do loop construction shown above does work, but the "bankloop" construction is easier. The construction begins with "BANKLOOP FAMILY." Within the bankloop one can access an element with "BANK%(ELEMENT)" and bank will be incremented to point at the next ID each iteration. This eliminates the need for you to use and increment pointers.
To do the above loop using bankloop, type:
Ida> BANKLOOP PHCHRG Ida> TYPE PHCHRG%(CHARGE) Ida> ENDWe get the same result with less work.
At the Ida prompt type:
Ida> OPENTAPE READ REC94_MDST STAGE WAIT Ida> GO 1 Ida> INDEX Ida> TYPE BANKCNT(_PHCHRG)
Index shows us that we have many more types of banks in memory that we had before. Bankcnt tells us we have 15 PHCHRG banks representing 15 changed tracks found in this event. We also see this count of 15 by looking at the second column of the index output.
Note anything following "!" is just a comment no need for you to type. At the Ida prompt type:
Ida> VAR PEVENT,PTOT,LAMBDA,PT !declare variables Ida> DEF EVANAL !define event analysis Ida> BANKLOOP PHCHRG !loop over all phchrg banks in event. Ida> LAMBDA = ATAN(PHCHRG%(HLXPAR(3))) !get angle lambda Ida> PT=1/PHCHRG%(HLXPAR(2)) !get pt Ida> PTOT=PT/COS(LAMBDA) !define Ptot Ida> HIST PTOT FROM 0 TO 50 ID 10 TITLE "MOMENTUM PER TRACK" Ida> PEVENT=PTOT+PEVENT Ida> END !End loop ever phchrg banks Ida> HIST PEVENT FROM 0 TO 100 ID 20 TITLE "MOMENTUM PER EVENT" Ida> PEVENT=0 !clear PEVENT for next event Ida> ENDDEF !end event loop Ida> go 100 !Do 100 events Ida> HOUT 10 SDDXWDO !Display histogram Ida> HOUT 20 SDDXWDO !Display histogram
REAL HLXPAR(6) " * track parameters and error matrix * "Unfortunately multiple dimensions on one variable are not allowed, e.g. Real D(10,10) is illegal. However there is a way around this problem using Data Blocks.
Data blocks are particularly useful when it is desirable to group a set of variables together logical, especially when you desire to repeat a set of variables a number of times. Blocks may occur anywhere within a bank including within other blocks. Blocks also provide a means of creating multiple dimension arrays. Again it is easier to learn by example. So lets look at the PHKLUS bank which contains information about calorimetry clusters. There should be one bank per cluster. Get a copy of PHKLUS.TEMPLATE in your editor.
You can do this by typing:
>
eve ducssearch:phklus.template
Search through the file until you find
Block LAYER(2:3) "Layer by layer info EM section" Integer NHIT "Number of towers hit" Real CTH "Mean cluster cos(theta) this layer (energy weighted)" Real WCTH "Width of energy in cos(theta)" Real PHI "Mean cluster phi in this layer (energy weighted)" Real WPHI "Width of energy in phi" Endblock
Here we see a block named "LAYER" representing the EM1 and EM2 sections of the LAC (Liquid Argon Calorimeter). For each layer the block contains the number of towers hit, the mean cos theta of cluster, the width of the cluster, the mean phi of cluster and the width in phi. Accessing information stored in a block is very similar to accessing a regular variable the form is POINTER%(BLOCK(NUMBER),VARIABLE). So the number of towers hit in EM1 of the first bank/cluster of a given event would be _PHKLUS%(LAYER(2),NHIT).
Let us plot the energy per layer vs costh of the cluster. Note in SLD Kalorimeter Coordinates layers 0-7 correspond to:
Note a line ending with a "-" tells ida the command is continued on the next line.
Ida> DEF EVANAL !Define event loop Ida> BANKLOOP PHKLUS Ida> EEM1=PHKLUS%(ELAYER(2)) Ida> CTEM1=PHKLUS%(LAYER(2),CTH) Ida> EEM2=PHKLUS%(ELAYER(3)) Ida> CTEM2=PHKLUS%(LAYER(3),CTH) Ida> SCAT EEM1 FROM 0 TO 40 VS CTEM1 FROM -1 TO 1 - Ida> ID 30 TITLE "EM1 COSTH ENERGY DISTRIBUTION" Ida> SCAT EEM2 FROM 0 TO 40 VS CTEM2 FROM -1 TO 1 - Ida> ID 40 TITLE "EM2 COSTH ENERGY DISTRIBUTION" Ida> END Ida> ENDDEF Ida> GO 300 Ida> HOUT 30 SDDXWDO Ida> HOUT 40 SDDXWDO
As mentioned earlier we can have blocks inside blocks for instance if we wanted to store all the clusters in one bank we could have something like.
Note the following is a fictitious bank created as an example for this exercise.
Bank Klusall context=fictitious Maxid=1 "fictitious bank for illustration" INTEGER NKLUS !number of clusters BLOCK CLUST(NKLUS) !cluster by cluster info section Real ERAW "Raw cluster energy (before e/pi correction)" Real CTH "Mean cluster cos(theta) (energy weighted)" Real WCTH "Width of cluster in cos(theta)" Real PHI "Mean cluster phi (energy weighted)" Real WPHI "Width of cluster in phi" Real Elayer(0:7) "energy by layer (MIP scale)" Block LAYER(2:3) "Layer by layer info EM section" Integer NHIT "Number of towers hit" Real CTH "Mean cluster cos(theta) this layer (energy weighted)" Real WCTH "Width of energy in cos(theta)" Real PHI "Mean cluster phi in this layer (energy weighted)" Real WPHI "Width of energy in phi" Endblock EndblockNow if one wanted to find Costh in Lac Em1 of the third cluster it would be:
_KLUSALL%(CLUST(3),LAYER(2),CTH)
This section was designed to give you a basic working understanding of Jazelle banks. By no means did we cover all the intricacies of Jazelle. However I hope things are a little less mysterious now. At some point when you are done with this workbook and have a little more experience working with banks you may want to read the official Jazelle Manual.