2 // Copyright (C) 2011 Ken Chapple <ken@mi-squared.com>
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
9 require_once(dirname(__FILE__
)."/../../../../clinical_rules.php");
11 abstract class AbstractCqmReport
implements RsReportIF
13 protected $_cqmPopulation;
15 protected $_resultsArray = array();
19 protected $_beginMeasurement;
20 protected $_endMeasurement;
22 public function __construct(array $rowRule, array $patientIdArray, $dateTarget)
24 // require all .php files in the report's sub-folder
25 $className = get_class($this);
26 foreach (glob(dirname(__FILE__
)."/../reports/".$className."/*.php") as $filename) {
27 require_once($filename);
30 // require common .php files
31 foreach (glob(dirname(__FILE__
)."/../reports/common/*.php") as $filename) {
32 require_once($filename);
35 // require clinical types
36 foreach (glob(dirname(__FILE__
)."/../../../ClinicalTypes/*.php") as $filename) {
37 require_once($filename);
40 $this->_cqmPopulation
= new CqmPopulation($patientIdArray);
41 $this->_rowRule
= $rowRule;
42 $this->_ruleId
= isset($rowRule['id']) ?
$rowRule['id'] : '';
43 // Calculate measurement period
44 $tempDateArray = explode("-", $dateTarget);
45 $tempYear = $tempDateArray[0];
46 $this->_beginMeasurement
= $tempDateArray[0] . "-01-01 00:00:00";
47 $this->_endMeasurement
= $tempDateArray[0] . "-12-31 23:59:59";
50 abstract public function createPopulationCriteria();
52 public function getBeginMeasurement()
54 return $this->_beginMeasurement
;
57 public function getEndMeasurement()
59 return $this->_endMeasurement
;
62 public function getResults()
64 return $this->_resultsArray
;
67 public function execute()
69 $populationCriterias = $this->createPopulationCriteria();
70 if (!is_array($populationCriterias)) {
71 $tmpPopulationCriterias = array();
72 $tmpPopulationCriterias[]= $populationCriterias;
73 $populationCriterias = $tmpPopulationCriterias;
76 foreach ($populationCriterias as $populationCriteria) {
77 // If itemization is turned on, then iterate the rule id iterator
78 if ($GLOBALS['report_itemizing_temp_flag_and_id']) {
79 $GLOBALS['report_itemized_test_id_iterator']++
;
82 if ($populationCriteria instanceof CqmPopulationCrtiteriaFactory
) {
83 $initialPatientPopulationFilter = $populationCriteria->createInitialPatientPopulation();
84 if (!$initialPatientPopulationFilter instanceof CqmFilterIF
) {
85 throw new Exception("InitialPatientPopulation must be an instance of CqmFilterIF");
88 $denominator = $populationCriteria->createDenominator();
89 if (!$denominator instanceof CqmFilterIF
) {
90 throw new Exception("Denominator must be an instance of CqmFilterIF");
93 $numerators = $populationCriteria->createNumerators();
94 if (!is_array($numerators)) {
95 $tmpNumerators = array();
96 $tmpNumerators[]= $numerators;
97 $numerators = $tmpNumerators;
100 $exclusion = $populationCriteria->createExclusion();
101 if (!$exclusion instanceof CqmFilterIF
) {
102 throw new Exception("Exclusion must be an instance of CqmFilterIF");
105 //Denominator Exception added
107 if (method_exists($populationCriteria, 'createDenominatorException')) {
111 $totalPatients = count($this->_cqmPopulation
);
112 $initialPatientPopulation = 0;
113 $denominatorPatientPopulation = 0;
114 $exclusionsPatientPopulation = 0;
115 $exceptionsPatientPopulation = 0; // this is a bridge to no where variable (calculated but not used below). Will keep for now, though.
116 $patExclArr = array();
117 $patExceptArr = array();
118 $numeratorPatientPopulations = $this->initNumeratorPopulations($numerators);
119 foreach ($this->_cqmPopulation
as $patient) {
120 if (!$initialPatientPopulationFilter->test($patient, $this->_beginMeasurement
, $this->_endMeasurement
)) {
124 $initialPatientPopulation++
;
126 // If itemization is turned on, then record the "Initial Patient population" item
127 if ($GLOBALS['report_itemizing_temp_flag_and_id']) {
128 insertItemReportTracker($GLOBALS['report_itemizing_temp_flag_and_id'], $GLOBALS['report_itemized_test_id_iterator'], 3, $patient->id
);
131 if (!$denominator->test($patient, $this->_beginMeasurement
, $this->_endMeasurement
)) {
135 $denominatorPatientPopulation++
;
137 if ($exclusion->test($patient, $this->_beginMeasurement
, $this->_endMeasurement
)) {
138 $exclusionsPatientPopulation++
;
139 $patExclArr[] = $patient->id
;
142 //Denominator Exception added
144 $denom_exception = $populationCriteria->createDenominatorException();
145 if ($denom_exception->test($patient, $this->_beginMeasurement
, $this->_endMeasurement
)) {
146 $exceptionsPatientPopulation++
; // this is a bridge to no where variable (not used below). Will keep for now, though.
147 $patExceptArr[] = $patient->id
;
151 foreach ($numerators as $numerator) {
152 $this->testNumerator($patient, $numerator, $numeratorPatientPopulations);
156 // tally results, run exclusion on each numerator
157 $pass_filt = $denominatorPatientPopulation;
158 $exclude_filt = $exclusionsPatientPopulation;
159 foreach ($numeratorPatientPopulations as $title => $pass_targ) {
160 if (count($patExclArr) > 0) {
161 foreach ($patExclArr as $patVal) {
162 // If itemization is turned on, then record the "excluded" item
163 if ($GLOBALS['report_itemizing_temp_flag_and_id']) {
164 insertItemReportTracker($GLOBALS['report_itemizing_temp_flag_and_id'], $GLOBALS['report_itemized_test_id_iterator'], 2, $patVal, $title);
169 if (count($patExceptArr) > 0) {
170 foreach ($patExceptArr as $patVal) {
171 // If itemization is turned on, then record the "exception" item
172 if ($GLOBALS['report_itemizing_temp_flag_and_id']) {
173 insertItemReportTracker($GLOBALS['report_itemizing_temp_flag_and_id'], $GLOBALS['report_itemized_test_id_iterator'], 4, $patVal, $title);
178 $percentage = calculate_percentage($pass_filt, $exclude_filt, $pass_targ);
179 $this->_resultsArray
[]= new CqmResult(
182 $populationCriteria->getTitle(),
188 $initialPatientPopulation,
189 $exceptionsPatientPopulation
195 return $this->_resultsArray
;
198 private function initNumeratorPopulations(array $numerators)
200 $numeratorPatientPopulations = array();
201 foreach ($numerators as $numerator) {
202 $numeratorPatientPopulations[$numerator->getTitle()] = 0;
205 return $numeratorPatientPopulations;
208 private function testNumerator($patient, $numerator, &$numeratorPatientPopulations)
210 if ($numerator instanceof CqmFilterIF
) {
211 if ($numerator->test($patient, $this->_beginMeasurement
, $this->_endMeasurement
)) {
212 $numeratorPatientPopulations[$numerator->getTitle()]++
;
214 // If itemization is turned on, then record the "passed" item
215 if ($GLOBALS['report_itemizing_temp_flag_and_id']) {
216 insertItemReportTracker($GLOBALS['report_itemizing_temp_flag_and_id'], $GLOBALS['report_itemized_test_id_iterator'], 1, $patient->id
, $numerator->getTitle());
219 // If itemization is turned on, then record the "failed" item
220 if ($GLOBALS['report_itemizing_temp_flag_and_id']) {
221 insertItemReportTracker($GLOBALS['report_itemizing_temp_flag_and_id'], $GLOBALS['report_itemized_test_id_iterator'], 0, $patient->id
, $numerator->getTitle());
225 throw new Exception("Numerator must be an instance of CqmFilterIF");