Modifying the PQM Template/Layout

Nov 29, 2016 at 1:56 PM
I am trying to customize the layout of the PDF generated from the Plan Quality Metrics script.
While there are a few elements I can customize from the 'gen_report.xsl' file, the majority of the layout seems to come from the stylesheet template.

If I want to make modifications to the PQMTable (e.g. remove/reorder the columns in the tables) how could I do so?

Completely new to C#, sorry if this is an easy one.
Thanks in advance.
Dec 12, 2016 at 2:47 PM
Is anyone able to help with removing columns from the PQM report tables?

Lee
Dec 19, 2016 at 5:12 PM
Hi Lee,

From what I gather, you are correct in the assumption that the gen_report.xsl file is controlling the actual layout you're getting in your report. This file seems to be in two parts. The first part is the CSS (cascading style sheets) that controls the visual layout of the page. Unless you want to change things like Table border style, font size, and color, this would not be the portion you want to change. The second part is the HTML markup for the page that gets displayed. This can be edited directly. For example, in the beams table:
<table  id="beamsTable" border="1">
      <tr>
        <th>#</th>
        <xsl:for-each select="Beams/Beam">
          <th>
            <xsl:value-of select="@Id"/>
          </th>
        </xsl:for-each>
      </tr>
      <tr>
        <th>Beam Type</th>
        <xsl:for-each select="Beams/Beam">
          <td>
            <xsl:choose>
              <xsl:when test="IsSetupField = 'true'">Setup</xsl:when>
              <xsl:otherwise>Treatment</xsl:otherwise>
            </xsl:choose>
          </td>
        </xsl:for-each>
      </tr>
      <tr>
        <th>Technique</th>
        <xsl:for-each select="Beams/Beam">
          <td>
            <xsl:value-of select="Technique/@Id"/>
          </td>
        </xsl:for-each>
      </tr>
      <tr>
        <th>Energy</th>
        <xsl:for-each select="Beams/Beam">
          <td>
            <xsl:value-of select="EnergyModeDisplayName"/>
          </td>
        </xsl:for-each>
      </tr>
      <tr>
        <th>Dose Rate</th>
        <xsl:for-each select="Beams/Beam">
          <td>
            <xsl:value-of select="DoseRate"/>
          </td>
        </xsl:for-each>
      </tr>
      <tr>
        <th>MU</th>
        <xsl:for-each select="Beams/Beam">
          <td>
            <xsl:value-of select="number(round(Meterset/Value*100) div 100.0)"/>
          </td>
        </xsl:for-each>
      </tr>
      <tr>
        <th>Dose</th>
        <xsl:for-each select="Beams/Beam">
          <td>
            <xsl:variable name="dose" select="number(round(FieldReferencePoints/FieldReferencePoint[IsPrimaryReferencePoint='true']/FieldDose/Dose*100) div 100.0)"/>
            <xsl:variable name="unit" select="FieldReferencePoints/FieldReferencePoint[IsPrimaryReferencePoint='true']/FieldDose/Unit"/>
            <xsl:value-of select="concat($dose, ' ', $unit)"/>
          </td>
        </xsl:for-each>
      </tr>
      <tr>
        <th>Gantry Start</th>
        <xsl:for-each select="BeamAndControlPoints/Beam">
          <td>
            <xsl:value-of select="ControlPoints/ControlPoint[1]/GantryAngle"/>
          </td>
        </xsl:for-each>
      </tr>
      <tr>
        <th>Gantry End</th>
        <xsl:for-each select="BeamAndControlPoints/Beam">
          <td>
            <xsl:value-of select="ControlPoints/ControlPoint[last()]/GantryAngle"/>
          </td>
        </xsl:for-each>
      </tr>
      <tr>
        <th>Gantry Direction</th>
        <xsl:for-each select="Beams/Beam">
          <td>
            <xsl:value-of select="GantryDirection"/>
          </td>
        </xsl:for-each>
      </tr>
    </table>
If I wanted to remove a row for the dose rate, I could simply remove the following code from the html above.
 <tr>
        <th>Dose Rate</th>
        <xsl:for-each select="Beams/Beam">
          <td>
            <xsl:value-of select="DoseRate"/>
          </td>
        </xsl:for-each>
      </tr>
But if you wanted to remove a column from a table (for instance the PQM table):
<table id="pqmTable" border="1">
          <tr>
            <th>Name</th>
            <th>Type</th>
            <th>Evaluation Point</th>
            <th>Calculated Value</th>
            <th>Goal</th>
            <th>Must</th>
            <th>Evaluation</th>
          </tr>
          <!-- call generatePQMTableRowData function -->
          <xsl:call-template name="generatePQMTableRowData">
            <xsl:with-param name="pqmNode" select="PQMs/PQM[1]"/>
            <xsl:with-param name="index" select="0"/>
          </xsl:call-template>
        </table>
This will be much more difficult. You see here, the first row is static, meaning you can easily remove a column from that row with no consequences. The other row is called dynamically, by the generatePQMTableRowData function that is located just beneath the code-snippet above (pasted below). You could go through this code snippet and find the corresponding <td> element to the column you want to remove and remove them as well. This will be a trial and error approach so make sure you are noting your changes so you can undo them if necessary.
 <xsl:template name="generatePQMTableRowData">
    <xsl:param name="pqmNode" />
    <xsl:param name="index" />
    <xsl:variable name="nextIndex" select="$index+1"/>
    <xsl:choose>
      <xsl:when test="not($pqmNode)">
        <!-- No current node, just exit function-->
<!--      !Exiting generatePointsTableRowData, index = <xsl:value-of select="$index"/> -->
      </xsl:when>
      <xsl:otherwise>
        <!-- figure out the units for the calculated value -->
        <xsl:variable name="volumeUnits">
          <xsl:choose>
            <xsl:when test="not($pqmNode/Volume)" />
            <xsl:otherwise>
              <xsl:choose>
                <xsl:when test="$pqmNode/Volume/@units = 'Relative'">%</xsl:when>
                <xsl:otherwise>cc</xsl:otherwise>
              </xsl:choose>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:variable name="calculatedValueUnits">
          <xsl:choose>
            <xsl:when test="$pqmNode/DoseValue/@calculated = 'True'">
              <xsl:value-of select="$pqmNode/DoseValue/@units"/>
            </xsl:when>
            <xsl:when test="$pqmNode/Volume/@calculated = 'True'">
              <xsl:value-of select="$volumeUnits"/>
            </xsl:when>
          </xsl:choose>
        </xsl:variable>
        <xsl:variable name="resultColor">
          <xsl:choose>
            <xsl:when test="$pqmNode/Evaluate/Result/PFW = 'PASS'">green</xsl:when>
            <xsl:when test="$pqmNode/Evaluate/Result/PFW = 'WARN'">yellow</xsl:when>
            <xsl:otherwise>red</xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        
        <tr>
          <td>
            <xsl:value-of select="$pqmNode/@name"/>
          </td>
          <td>
            <xsl:value-of select="$pqmNode/@type"/>
          </td>
          <xsl:choose>
            <xsl:when test="$pqmNode/DoseValue/@calculated = 'True'">
              <td>
                <xsl:value-of select="concat($pqmNode/Volume, ' ', $volumeUnits)"/>
              </td>
              <td>
                <xsl:value-of select="concat($pqmNode/DoseValue, ' ', $pqmNode/DoseValue/@units)"/>
              </td>
            </xsl:when>
            <xsl:when test="$pqmNode/Volume/@calculated = 'True'">
              <td>
                <xsl:value-of select="concat($pqmNode/DoseValue, ' ', $pqmNode/DoseValue/@units)"/>
              </td>
              <td>
                <xsl:value-of select="concat($pqmNode/Volume, ' ', $volumeUnits)"/>
              </td>
            </xsl:when>
          </xsl:choose>
          <td>
            <xsl:value-of select="concat($pqmNode/Evaluate/Limit, ' ', $calculatedValueUnits)"/>
          </td>
          <td>
            <xsl:value-of select="concat($pqmNode/Evaluate/Result/MaxLimit, ' ', $calculatedValueUnits)"/>
          </td>
          <td class="{$pqmNode/Evaluate/Result/PFW}">
            <xsl:value-of select="$pqmNode/Evaluate/Result/PFW"/>
          </td>
        </tr>
        <!-- recursively call this function -->
        <xsl:call-template name="generatePQMTableRowData">
          <xsl:with-param name="pqmNode" select="$pqmNode/following-sibling::PQM[1]"/>
          <xsl:with-param   name="index" select="$nextIndex"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
Best regards,