Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/bin/env python 

2 

3""" 

4camcops_server/tasks/icd10depressive.py 

5 

6=============================================================================== 

7 

8 Copyright (C) 2012-2020 Rudolf Cardinal (rudolf@pobox.com). 

9 

10 This file is part of CamCOPS. 

11 

12 CamCOPS is free software: you can redistribute it and/or modify 

13 it under the terms of the GNU General Public License as published by 

14 the Free Software Foundation, either version 3 of the License, or 

15 (at your option) any later version. 

16 

17 CamCOPS is distributed in the hope that it will be useful, 

18 but WITHOUT ANY WARRANTY; without even the implied warranty of 

19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

20 GNU General Public License for more details. 

21 

22 You should have received a copy of the GNU General Public License 

23 along with CamCOPS. If not, see <https://www.gnu.org/licenses/>. 

24 

25=============================================================================== 

26 

27""" 

28 

29from typing import List, Optional 

30 

31from cardinal_pythonlib.datetimefunc import format_datetime 

32import cardinal_pythonlib.rnc_web as ws 

33from sqlalchemy.sql.schema import Column 

34from sqlalchemy.sql.sqltypes import Boolean, Date, Integer, UnicodeText 

35 

36from camcops_server.cc_modules.cc_constants import ( 

37 CssClass, 

38 DateFormat, 

39 ICD10_COPYRIGHT_DIV, 

40) 

41from camcops_server.cc_modules.cc_ctvinfo import CTV_INCOMPLETE, CtvInfo 

42from camcops_server.cc_modules.cc_html import ( 

43 answer, 

44 get_present_absent_none, 

45 heading_spanning_two_columns, 

46 tr, 

47 tr_qa, 

48) 

49from camcops_server.cc_modules.cc_request import CamcopsRequest 

50from camcops_server.cc_modules.cc_sqla_coltypes import ( 

51 BIT_CHECKER, 

52 CamcopsColumn, 

53 SummaryCategoryColType, 

54) 

55from camcops_server.cc_modules.cc_string import AS 

56from camcops_server.cc_modules.cc_summaryelement import SummaryElement 

57from camcops_server.cc_modules.cc_task import ( 

58 Task, 

59 TaskHasClinicianMixin, 

60 TaskHasPatientMixin, 

61) 

62from camcops_server.cc_modules.cc_text import SS 

63 

64 

65# ============================================================================= 

66# Icd10Depressive 

67# ============================================================================= 

68 

69class Icd10Depressive(TaskHasClinicianMixin, TaskHasPatientMixin, Task): 

70 """ 

71 Server implementation of the ICD10-DEPR task. 

72 """ 

73 __tablename__ = "icd10depressive" 

74 shortname = "ICD10-DEPR" 

75 

76 mood = CamcopsColumn( 

77 "mood", Boolean, 

78 permitted_value_checker=BIT_CHECKER, 

79 comment="Depressed mood to a degree that is definitely abnormal " 

80 "for the individual, present for most of the day and almost " 

81 "every day, largely uninfluenced by circumstances, and " 

82 "sustained for at least 2 weeks." 

83 ) 

84 anhedonia = CamcopsColumn( 

85 "anhedonia", Boolean, 

86 permitted_value_checker=BIT_CHECKER, 

87 comment="Loss of interest or pleasure in activities that are " 

88 "normally pleasurable." 

89 ) 

90 energy = CamcopsColumn( 

91 "energy", Boolean, 

92 permitted_value_checker=BIT_CHECKER, 

93 comment="Decreased energy or increased fatiguability." 

94 ) 

95 

96 sleep = CamcopsColumn( 

97 "sleep", Boolean, 

98 permitted_value_checker=BIT_CHECKER, 

99 comment="Sleep disturbance of any type." 

100 ) 

101 worth = CamcopsColumn( 

102 "worth", Boolean, 

103 permitted_value_checker=BIT_CHECKER, 

104 comment="Loss of confidence and self-esteem." 

105 ) 

106 appetite = CamcopsColumn( 

107 "appetite", Boolean, 

108 permitted_value_checker=BIT_CHECKER, 

109 comment="Change in appetite (decrease or increase) with " 

110 "corresponding weight change." 

111 ) 

112 guilt = CamcopsColumn( 

113 "guilt", Boolean, 

114 permitted_value_checker=BIT_CHECKER, 

115 comment="Unreasonable feelings of self-reproach or excessive and " 

116 "inappropriate guilt." 

117 ) 

118 concentration = CamcopsColumn( 

119 "concentration", Boolean, 

120 permitted_value_checker=BIT_CHECKER, 

121 comment="Complaints or evidence of diminished ability to think " 

122 "or concentrate, such as indecisiveness or vacillation." 

123 ) 

124 activity = CamcopsColumn( 

125 "activity", Boolean, 

126 permitted_value_checker=BIT_CHECKER, 

127 comment="Change in psychomotor activity, with agitation or " 

128 "retardation (either subjective or objective)." 

129 ) 

130 death = CamcopsColumn( 

131 "death", Boolean, 

132 permitted_value_checker=BIT_CHECKER, 

133 comment="Recurrent thoughts of death or suicide, or any " 

134 "suicidal behaviour." 

135 ) 

136 

137 somatic_anhedonia = CamcopsColumn( 

138 "somatic_anhedonia", Boolean, 

139 permitted_value_checker=BIT_CHECKER, 

140 comment="Marked loss of interest or pleasure in activities that " 

141 "are normally pleasurable" 

142 ) 

143 somatic_emotional_unreactivity = CamcopsColumn( 

144 "somatic_emotional_unreactivity", Boolean, 

145 permitted_value_checker=BIT_CHECKER, 

146 comment="Lack of emotional reactions to events or " 

147 "activities that normally produce an emotional response" 

148 ) 

149 somatic_early_morning_waking = CamcopsColumn( 

150 "somatic_early_morning_waking", Boolean, 

151 permitted_value_checker=BIT_CHECKER, 

152 comment="Waking in the morning 2 hours or more before " 

153 "the usual time" 

154 ) 

155 somatic_mood_worse_morning = CamcopsColumn( 

156 "somatic_mood_worse_morning", Boolean, 

157 permitted_value_checker=BIT_CHECKER, 

158 comment="Depression worse in the morning" 

159 ) 

160 somatic_psychomotor = CamcopsColumn( 

161 "somatic_psychomotor", Boolean, 

162 permitted_value_checker=BIT_CHECKER, 

163 comment="Objective evidence of marked psychomotor retardation or " 

164 "agitation (remarked on or reported by other people)" 

165 ) 

166 somatic_appetite = CamcopsColumn( 

167 "somatic_appetite", Boolean, 

168 permitted_value_checker=BIT_CHECKER, 

169 comment="Marked loss of appetite" 

170 ) 

171 somatic_weight = CamcopsColumn( 

172 "somatic_weight", Boolean, 

173 permitted_value_checker=BIT_CHECKER, 

174 comment="Weight loss (5 percent or more of body weight in the past " 

175 "month)" 

176 # 2017-08-24: AVOID A PERCENT SYMBOL (%) FOR NOW; SEE THIS BUG: 

177 # https://bitbucket.org/zzzeek/sqlalchemy/issues/4052/comment-attribute-causes-crash-during # noqa 

178 ) 

179 somatic_libido = CamcopsColumn( 

180 "somatic_libido", Boolean, 

181 permitted_value_checker=BIT_CHECKER, 

182 comment="Marked loss of libido" 

183 ) 

184 

185 hallucinations_schizophrenic = CamcopsColumn( 

186 "hallucinations_schizophrenic", Boolean, 

187 permitted_value_checker=BIT_CHECKER, 

188 comment="Hallucinations that are 'typically schizophrenic' " 

189 "(hallucinatory voices giving a running commentary on the " 

190 "patient's behaviour, or discussing him between themselves, " 

191 "or other types of hallucinatory voices coming from some part " 

192 "of the body)." 

193 ) 

194 hallucinations_other = CamcopsColumn( 

195 "hallucinations_other", Boolean, 

196 permitted_value_checker=BIT_CHECKER, 

197 comment="Hallucinations (of any other kind)." 

198 ) 

199 delusions_schizophrenic = CamcopsColumn( 

200 "delusions_schizophrenic", Boolean, 

201 permitted_value_checker=BIT_CHECKER, 

202 comment="Delusions that are 'typically schizophrenic' (delusions " 

203 "of control, influence or passivity, clearly referred to body " 

204 "or limb movements or specific thoughts, actions, or " 

205 "sensations; delusional perception; persistent delusions of " 

206 "other kinds that are culturally inappropriate and completely " 

207 "impossible).") 

208 delusions_other = CamcopsColumn( 

209 "delusions_other", Boolean, 

210 permitted_value_checker=BIT_CHECKER, 

211 comment="Delusions (of any other kind)." 

212 ) 

213 stupor = CamcopsColumn( 

214 "stupor", Boolean, 

215 permitted_value_checker=BIT_CHECKER, 

216 comment="Depressive stupor." 

217 ) 

218 

219 date_pertains_to = CamcopsColumn( 

220 "date_pertains_to", Date, 

221 comment="Date the assessment pertains to" 

222 ) 

223 comments = Column( 

224 "comments", UnicodeText, 

225 comment="Clinician's comments" 

226 ) 

227 duration_at_least_2_weeks = CamcopsColumn( 

228 "duration_at_least_2_weeks", Boolean, 

229 permitted_value_checker=BIT_CHECKER, 

230 comment="Depressive episode lasts at least 2 weeks?" 

231 ) 

232 severe_clinically = CamcopsColumn( 

233 "severe_clinically", Boolean, 

234 permitted_value_checker=BIT_CHECKER, 

235 comment="Clinical impression of severe depression, in a " 

236 "patient unwilling or unable to describe many symptoms in " 

237 "detail" 

238 ) 

239 

240 CORE_NAMES = ["mood", "anhedonia", "energy"] 

241 ADDITIONAL_NAMES = ["sleep", "worth", "appetite", "guilt", "concentration", 

242 "activity", "death"] 

243 SOMATIC_NAMES = [ 

244 "somatic_anhedonia", "somatic_emotional_unreactivity", 

245 "somatic_early_morning_waking", "somatic_mood_worse_morning", 

246 "somatic_psychomotor", "somatic_appetite", 

247 "somatic_weight", "somatic_libido" 

248 ] 

249 PSYCHOSIS_NAMES = [ 

250 "hallucinations_schizophrenic", "hallucinations_other", 

251 "delusions_schizophrenic", "delusions_other", 

252 "stupor" 

253 ] 

254 

255 @staticmethod 

256 def longname(req: "CamcopsRequest") -> str: 

257 _ = req.gettext 

258 return _( 

259 "ICD-10 symptomatic criteria for a depressive episode " 

260 "(as in e.g. F06.3, F25, F31, F32, F33)" 

261 ) 

262 

263 def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]: 

264 if not self.is_complete(): 

265 return CTV_INCOMPLETE 

266 infolist = [CtvInfo( 

267 content="Pertains to: {}. Category: {}.".format( 

268 format_datetime(self.date_pertains_to, DateFormat.LONG_DATE), 

269 self.get_full_description(req) 

270 ) 

271 )] 

272 if self.comments: 

273 infolist.append(CtvInfo(content=ws.webify(self.comments))) 

274 return infolist 

275 

276 def get_summaries(self, req: CamcopsRequest) -> List[SummaryElement]: 

277 return self.standard_task_summary_fields() + [ 

278 SummaryElement( 

279 name="n_core", 

280 coltype=Integer(), 

281 value=self.n_core(), 

282 comment="Number of core diagnostic symptoms (/3)"), 

283 SummaryElement( 

284 name="n_additional", 

285 coltype=Integer(), 

286 value=self.n_additional(), 

287 comment="Number of additional diagnostic symptoms (/7)"), 

288 SummaryElement( 

289 name="n_total", 

290 coltype=Integer(), 

291 value=self.n_total(), 

292 comment="Total number of diagnostic symptoms (/10)"), 

293 SummaryElement( 

294 name="n_somatic", 

295 coltype=Integer(), 

296 value=self.n_somatic(), 

297 comment="Number of somatic syndrome symptoms (/8)"), 

298 SummaryElement( 

299 name="category", 

300 coltype=SummaryCategoryColType, 

301 value=self.get_full_description(req), 

302 comment="Diagnostic category"), 

303 SummaryElement( 

304 name="psychosis_or_stupor", 

305 coltype=Boolean(), 

306 value=self.is_psychotic_or_stupor(), 

307 comment="Psychotic symptoms or stupor present?"), 

308 ] 

309 

310 # Scoring 

311 def n_core(self) -> int: 

312 return self.count_booleans(self.CORE_NAMES) 

313 

314 def n_additional(self) -> int: 

315 return self.count_booleans(self.ADDITIONAL_NAMES) 

316 

317 def n_total(self) -> int: 

318 return self.n_core() + self.n_additional() 

319 

320 def n_somatic(self) -> int: 

321 return self.count_booleans(self.SOMATIC_NAMES) 

322 

323 def main_complete(self) -> bool: 

324 return ( 

325 self.duration_at_least_2_weeks is not None and 

326 self.all_fields_not_none(self.CORE_NAMES) and 

327 self.all_fields_not_none(self.ADDITIONAL_NAMES) 

328 ) or bool( 

329 self.severe_clinically 

330 ) 

331 

332 # Meets criteria? These also return null for unknown. 

333 def meets_criteria_severe_psychotic_schizophrenic(self) -> Optional[bool]: 

334 x = self.meets_criteria_severe_ignoring_psychosis() 

335 if not x: 

336 return x 

337 if self.stupor or self.hallucinations_other or self.delusions_other: 

338 return False # that counts as F32.3 

339 if (self.stupor is None or self.hallucinations_other is None or 

340 self.delusions_other is None): 

341 return None # might be F32.3 

342 if self.hallucinations_schizophrenic or self.delusions_schizophrenic: 

343 return True 

344 if (self.hallucinations_schizophrenic is None or 

345 self.delusions_schizophrenic is None): 

346 return None 

347 return False 

348 

349 def meets_criteria_severe_psychotic_icd(self) -> Optional[bool]: 

350 x = self.meets_criteria_severe_ignoring_psychosis() 

351 if not x: 

352 return x 

353 if self.stupor or self.hallucinations_other or self.delusions_other: 

354 return True 

355 if (self.stupor is None or 

356 self.hallucinations_other is None or 

357 self.delusions_other is None): 

358 return None 

359 return False 

360 

361 def meets_criteria_severe_nonpsychotic(self) -> Optional[bool]: 

362 x = self.meets_criteria_severe_ignoring_psychosis() 

363 if not x: 

364 return x 

365 if self.any_fields_none(self.PSYCHOSIS_NAMES): 

366 return None 

367 return self.count_booleans(self.PSYCHOSIS_NAMES) == 0 

368 

369 def meets_criteria_severe_ignoring_psychosis(self) -> Optional[bool]: 

370 if self.severe_clinically: 

371 return True 

372 if self.duration_at_least_2_weeks is not None \ 

373 and not self.duration_at_least_2_weeks: 

374 return False # too short 

375 if self.n_core() >= 3 and self.n_total() >= 8: 

376 return True 

377 if not self.main_complete(): 

378 return None # addition of more information might increase severity 

379 return False 

380 

381 def meets_criteria_moderate(self) -> Optional[bool]: 

382 if self.severe_clinically: 

383 return False # too severe 

384 if self.duration_at_least_2_weeks is not None \ 

385 and not self.duration_at_least_2_weeks: 

386 return False # too short 

387 if self.n_core() >= 3 and self.n_total() >= 8: 

388 return False # too severe; that's severe 

389 if not self.main_complete(): 

390 return None # addition of more information might increase severity 

391 if self.n_core() >= 2 and self.n_total() >= 6: 

392 return True 

393 return False 

394 

395 def meets_criteria_mild(self) -> Optional[bool]: 

396 if self.severe_clinically: 

397 return False # too severe 

398 if self.duration_at_least_2_weeks is not None \ 

399 and not self.duration_at_least_2_weeks: 

400 return False # too short 

401 if self.n_core() >= 2 and self.n_total() >= 6: 

402 return False # too severe; that's moderate 

403 if not self.main_complete(): 

404 return None # addition of more information might increase severity 

405 if self.n_core() >= 2 and self.n_total() >= 4: 

406 return True 

407 return False 

408 

409 def meets_criteria_none(self) -> Optional[bool]: 

410 if self.severe_clinically: 

411 return False # too severe 

412 if self.duration_at_least_2_weeks is not None \ 

413 and not self.duration_at_least_2_weeks: 

414 return True # too short for depression 

415 if self.n_core() >= 2 and self.n_total() >= 4: 

416 return False # too severe 

417 if not self.main_complete(): 

418 return None # addition of more information might increase severity 

419 return True 

420 

421 def meets_criteria_somatic(self) -> Optional[bool]: 

422 t = self.n_somatic() 

423 u = self.n_fields_none(self.SOMATIC_NAMES) 

424 if t >= 4: 

425 return True 

426 elif t + u < 4: 

427 return False 

428 else: 

429 return None 

430 

431 def get_somatic_description(self, req: CamcopsRequest) -> str: 

432 s = self.meets_criteria_somatic() 

433 if s is None: 

434 return self.wxstring(req, "category_somatic_unknown") 

435 elif s: 

436 return self.wxstring(req, "category_with_somatic") 

437 else: 

438 return self.wxstring(req, "category_without_somatic") 

439 

440 def get_main_description(self, req: CamcopsRequest) -> str: 

441 if self.meets_criteria_severe_psychotic_schizophrenic(): 

442 return self.wxstring(req, "category_severe_psychotic_schizophrenic") 

443 

444 elif self.meets_criteria_severe_psychotic_icd(): 

445 return self.wxstring(req, "category_severe_psychotic") 

446 

447 elif self.meets_criteria_severe_nonpsychotic(): 

448 return self.wxstring(req, "category_severe_nonpsychotic") 

449 

450 elif self.meets_criteria_moderate(): 

451 return self.wxstring(req, "category_moderate") 

452 

453 elif self.meets_criteria_mild(): 

454 return self.wxstring(req, "category_mild") 

455 

456 elif self.meets_criteria_none(): 

457 return self.wxstring(req, "category_none") 

458 

459 else: 

460 return req.sstring(SS.UNKNOWN) 

461 

462 def get_full_description(self, req: CamcopsRequest) -> str: 

463 skip_somatic = self.main_complete() and self.meets_criteria_none() 

464 return ( 

465 self.get_main_description(req) + 

466 ("" if skip_somatic else " " + self.get_somatic_description(req)) 

467 ) 

468 

469 def is_psychotic_or_stupor(self) -> Optional[bool]: 

470 if self.count_booleans(self.PSYCHOSIS_NAMES) > 0: 

471 return True 

472 elif self.all_fields_not_none(self.PSYCHOSIS_NAMES) > 0: 

473 return False 

474 else: 

475 return None 

476 

477 def is_complete(self) -> bool: 

478 return ( 

479 self.date_pertains_to is not None and 

480 self.main_complete() and 

481 self.field_contents_valid() 

482 ) 

483 

484 def text_row(self, req: CamcopsRequest, wstringname: str) -> str: 

485 return heading_spanning_two_columns(self.wxstring(req, wstringname)) 

486 

487 def row_true_false(self, req: CamcopsRequest, fieldname: str) -> str: 

488 return self.get_twocol_bool_row_true_false( 

489 req, fieldname, self.wxstring(req, "" + fieldname)) 

490 

491 def row_present_absent(self, req: CamcopsRequest, fieldname: str) -> str: 

492 return self.get_twocol_bool_row_present_absent( 

493 req, fieldname, self.wxstring(req, "" + fieldname)) 

494 

495 def get_task_html(self, req: CamcopsRequest) -> str: 

496 h = """ 

497 {clinician_comments} 

498 <div class="{CssClass.SUMMARY}"> 

499 <table class="{CssClass.SUMMARY}"> 

500 {tr_is_complete} 

501 {date_pertains_to} 

502 {category} 

503 {n_core} 

504 {n_total} 

505 {n_somatic} 

506 {psychotic_symptoms_or_stupor} 

507 </table> 

508 </div> 

509 <div class="{CssClass.EXPLANATION}"> 

510 {icd10_symptomatic_disclaimer} 

511 </div> 

512 <table class="{CssClass.TASKDETAIL}"> 

513 <tr> 

514 <th width="80%">Question</th> 

515 <th width="20%">Answer</th> 

516 </tr> 

517 """.format( 

518 clinician_comments=self.get_standard_clinician_comments_block( 

519 req, self.comments), 

520 CssClass=CssClass, 

521 tr_is_complete=self.get_is_complete_tr(req), 

522 date_pertains_to=tr_qa( 

523 req.wappstring(AS.DATE_PERTAINS_TO), 

524 format_datetime(self.date_pertains_to, DateFormat.LONG_DATE, 

525 default=None) 

526 ), 

527 category=tr_qa( 

528 req.sstring(SS.CATEGORY) + " <sup>[1,2]</sup>", 

529 self.get_full_description(req) 

530 ), 

531 n_core=tr( 

532 self.wxstring(req, "n_core"), 

533 answer(self.n_core()) + " / 3" 

534 ), 

535 n_total=tr( 

536 self.wxstring(req, "n_total"), 

537 answer(self.n_total()) + " / 10" 

538 ), 

539 n_somatic=tr( 

540 self.wxstring(req, "n_somatic"), 

541 answer(self.n_somatic()) + " / 8" 

542 ), 

543 psychotic_symptoms_or_stupor=tr( 

544 self.wxstring(req, "psychotic_symptoms_or_stupor") + 

545 " <sup>[2]</sup>", 

546 answer(get_present_absent_none( 

547 req, self.is_psychotic_or_stupor())) 

548 ), 

549 icd10_symptomatic_disclaimer=req.wappstring( 

550 AS.ICD10_SYMPTOMATIC_DISCLAIMER), 

551 ) 

552 

553 h += self.text_row(req, "duration_text") 

554 h += self.row_true_false(req, "duration_at_least_2_weeks") 

555 

556 h += self.text_row(req, "core") 

557 for x in self.CORE_NAMES: 

558 h += self.row_present_absent(req, x) 

559 

560 h += self.text_row(req, "additional") 

561 for x in self.ADDITIONAL_NAMES: 

562 h += self.row_present_absent(req, x) 

563 

564 h += self.text_row(req, "clinical_text") 

565 h += self.row_true_false(req, "severe_clinically") 

566 

567 h += self.text_row(req, "somatic") 

568 for x in self.SOMATIC_NAMES: 

569 h += self.row_present_absent(req, x) 

570 

571 h += self.text_row(req, "psychotic") 

572 for x in self.PSYCHOSIS_NAMES: 

573 h += self.row_present_absent(req, x) 

574 

575 extradetail = [ 

576 f"n_core() = {self.n_core()}", 

577 f"n_additional() = {self.n_additional()}", 

578 f"n_total() = {self.n_total()}", 

579 f"n_somatic() = {self.n_somatic()}", 

580 f"main_complete() = {self.main_complete()}", 

581 f"meets_criteria_severe_psychotic_schizophrenic() = {self.meets_criteria_severe_psychotic_schizophrenic()}", # noqa 

582 f"meets_criteria_severe_psychotic_icd() = {self.meets_criteria_severe_psychotic_icd()}", # noqa 

583 f"meets_criteria_severe_nonpsychotic() = {self.meets_criteria_severe_nonpsychotic()}", # noqa 

584 f"meets_criteria_severe_ignoring_psychosis() = {self.meets_criteria_severe_ignoring_psychosis()}", # noqa 

585 f"meets_criteria_moderate() = {self.meets_criteria_moderate()}", 

586 f"meets_criteria_mild() = {self.meets_criteria_mild()}", 

587 f"meets_criteria_none() = {self.meets_criteria_none()}", 

588 f"meets_criteria_somatic() = {self.meets_criteria_somatic()}", 

589 ] 

590 

591 h += f""" 

592 </table> 

593 <div class="{CssClass.HEADING}">Working</div> 

594 <div class="{CssClass.EXTRADETAIL2}"> 

595 <pre>{"<br>".join(ws.webify(f"‣ {x}") for x in extradetail)}</pre> 

596 </div> 

597 <div class="{CssClass.FOOTNOTES}"> 

598 [1] Mild depression requires ≥2 core symptoms and ≥4 total 

599 diagnostic symptoms. 

600 Moderate depression requires ≥2 core and ≥6 total. 

601 Severe depression requires 3 core and ≥8 total. 

602 All three require a duration of ≥2 weeks. 

603 In addition, the diagnosis of severe depression is allowed with 

604 a clinical impression of “severe” in a patient unable/unwilling 

605 to describe symptoms in detail. 

606 [2] ICD-10 nonpsychotic severe depression requires severe 

607 depression without hallucinations/delusions/depressive stupor. 

608 ICD-10 psychotic depression requires severe depression plus 

609 hallucinations/delusions other than those that are “typically 

610 schizophrenic”, or stupor. 

611 ICD-10 does not clearly categorize severe depression with only 

612 schizophreniform psychotic symptoms; 

613 however, such symptoms can occur in severe depression with 

614 psychosis (e.g. Tandon R &amp; Greden JF, 1987, PMID 2884810). 

615 Moreover, psychotic symptoms can occur in mild/moderate 

616 depression (Maj M et al., 2007, PMID 17915981). 

617 </div> 

618 {ICD10_COPYRIGHT_DIV} 

619 """ # noqa 

620 return h